MFC多线程编程,线程控制

tr3301103 2014-06-24 08:07:08
首先我用CreateThread()创建一个查看数据库的线程,线程函数:DWORD WINAPI SQListenProc(LPVOID lParam)
此线程的任务:不停的查看数据库中的一个表是否有新的数据插入,一旦有新的数据插入,就将新的数据取出来放入一个队列。
然后建立N个工作线程,所有工作线程共用一个线程函数:DWORD WINAPI WorkerProc(LPVOID lParam)
此线程的任务:查看队列中是否有数据,若有对该数据进行操作。
现在,我要实现的是:为了让工作线程尽可能少的做无用功,一开始将线程挂起,监听线程搜索到新的数据放入队列后,激活所有工作线程,每个工作线程循环工作,直到队列中的数据全部处理完后,自动挂起,等待监听线程下一次的激活。
请问要怎么实现?
我试过用CEvent,但是它一次只能激活一个线程。还有一个问题就是,多个线程共用一个线程函数时,如何在线程函数中获得线程句柄或是线程ID号?
问题有点大,希望有高手能够指点一下?
...全文
210 8 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
信阳毛尖 2014-06-25
  • 打赏
  • 举报
回复
引用 7 楼 GLSC_CENA 的回复:
[quote=引用 6 楼 lsq19871207 的回复:]

HEVENT __hEvent__ = ::CreateEvent(NULL, TRUE, FALSE, NULL) //手动重置,初始无信号
CRITICAL_SECTION __cs__={0};   //用于控制工作线程间互斥
InitializeCriticalSection(&__cs__);
BOOL  bFlag = FALSE;   //工作线程是否已处理过

DWORD WINAPI WorkerProc(LPVOID lParam)
{
	if(!bFlag)
    {
        ::WaitForSingleObject(__hEvent__ ,INFINITE);	 //当有新数据插入时手动置为有信号,bFlag = FALSE;
        do
        {
			if(bFlag)          //双重检测
			{
                ::EnterCriticalSection(&__cs__);
				//...........
				//...........
                ::LeaveCriticalSection(&__cs__);
				bFlag = TRUE;
			}
        }while(0);
        //ResetEvent(__hEvent__ );
	}
	return 0;
}

::CloseHandle(__hEvent__ );
::DeleteCriticalSection(&__cs__);
if(bFlag) //双重检测 { ::EnterCriticalSection(&__cs__); //........... //........... ::LeaveCriticalSection(&__cs__); bFlag = TRUE; } 这个逻辑有没有问题,如果bFlag为真,运行判断并置bFlag为真[/quote] 错了错了,少个! if(!bFlag) //双重检测
这个娜戒海了 2014-06-25
  • 打赏
  • 举报
回复
引用 6 楼 lsq19871207 的回复:

HEVENT __hEvent__ = ::CreateEvent(NULL, TRUE, FALSE, NULL) //手动重置,初始无信号
CRITICAL_SECTION __cs__={0};   //用于控制工作线程间互斥
InitializeCriticalSection(&__cs__);
BOOL  bFlag = FALSE;   //工作线程是否已处理过

DWORD WINAPI WorkerProc(LPVOID lParam)
{
	if(!bFlag)
    {
        ::WaitForSingleObject(__hEvent__ ,INFINITE);	 //当有新数据插入时手动置为有信号,bFlag = FALSE;
        do
        {
			if(bFlag)          //双重检测
			{
                ::EnterCriticalSection(&__cs__);
				//...........
				//...........
                ::LeaveCriticalSection(&__cs__);
				bFlag = TRUE;
			}
        }while(0);
        //ResetEvent(__hEvent__ );
	}
	return 0;
}

::CloseHandle(__hEvent__ );
::DeleteCriticalSection(&__cs__);
if(bFlag) //双重检测 { ::EnterCriticalSection(&__cs__); //........... //........... ::LeaveCriticalSection(&__cs__); bFlag = TRUE; } 这个逻辑有没有问题,如果bFlag为真,运行判断并置bFlag为真
信阳毛尖 2014-06-25
  • 打赏
  • 举报
回复

HEVENT __hEvent__ = ::CreateEvent(NULL, TRUE, FALSE, NULL) //手动重置,初始无信号
CRITICAL_SECTION __cs__={0};   //用于控制工作线程间互斥
InitializeCriticalSection(&__cs__);
BOOL  bFlag = FALSE;   //工作线程是否已处理过

DWORD WINAPI WorkerProc(LPVOID lParam)
{
	if(!bFlag)
    {
        ::WaitForSingleObject(__hEvent__ ,INFINITE);	 //当有新数据插入时手动置为有信号,bFlag = FALSE;
        do
        {
			if(bFlag)          //双重检测
			{
                ::EnterCriticalSection(&__cs__);
				//...........
				//...........
                ::LeaveCriticalSection(&__cs__);
				bFlag = TRUE;
			}
        }while(0);
        //ResetEvent(__hEvent__ );
	}
	return 0;
}

::CloseHandle(__hEvent__ );
::DeleteCriticalSection(&__cs__);
信阳毛尖 2014-06-25
  • 打赏
  • 举报
回复
但是,SetEvent()貌似只能激活一个工作线程,不可能执行一次,把所有线程都激活。 -------------------------------------------------------------------------------------------------------------------------- 你的工作线程不是共用一个线程函数吗? 再说,当这些工作线程都激活之后,也不可能是并行处理的,因为他们的处理函数是同一个,并行处理会乱掉的,必须控制互斥! HEVENT __hEvent__ = ::CreateEvent(NULL, TRUE, FALSE, NULL) //手动重置,初始无信号 CRITICAL_SECTION __cs__={0}; //用于控制工作线程间互斥 InitializeCriticalSection(&__cs__); BOOL bFlag = FALSE; //工作线程是否已处理过 DWORD WINAPI WorkerProc(LPVOID lParam) { if(!bFlag) { ::WaitForSingleObject(__hEvent__ ,INFINITE); //当有新数据插入时手动置为有信号,bFlag = FALSE; do { if(bFlag) //双重检测 { ::EnterCriticalSection(&__cs__); ........... ........... ::LeaveCriticalSection(&__cs__); bFlag = TRUE; } }while(0); //ResetEvent(__hEvent__ ); } return 0; } ::CloseHandle(__hEvent__ ); ::DeleteCriticalSection(&__cs__);
tr3301103 2014-06-25
  • 打赏
  • 举报
回复
引用 3 楼 tr3301103 的回复:
[quote=引用 1 楼 piaobotudou 的回复:] 1. CEvent可以CreateEvent(NULL, TRUE, FALSE, NULL)手动重置,配合CRITICAL_SECTION使用 当有新数据插入时SetEvent,当为空时ResetEvent
但是,SetEvent()貌似只能激活一个工作线程,不可能执行一次,把所有线程都激活。[/quote] Sorry,我错了。一开始对CreateEvent 的自动手动不是很理解,现在貌似可以了,谢谢!!
tr3301103 2014-06-25
  • 打赏
  • 举报
回复
引用 1 楼 piaobotudou 的回复:
1. CEvent可以CreateEvent(NULL, TRUE, FALSE, NULL)手动重置,配合CRITICAL_SECTION使用 当有新数据插入时SetEvent,当为空时ResetEvent
但是,SetEvent()貌似只能激活一个工作线程,不可能执行一次,把所有线程都激活。
微型蚂蚁 2014-06-25
  • 打赏
  • 举报
回复
2. GetCurrentThread(); GetCurrentThreadId();
微型蚂蚁 2014-06-25
  • 打赏
  • 举报
回复
1. CEvent可以CreateEvent(NULL, TRUE, FALSE, NULL)手动重置,配合CRITICAL_SECTION使用 当有新数据插入时SetEvent,当为空时ResetEvent

15,473

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧