windows下主线程同步

windows线程间同步方式

  • PostMessage、SendMessage、PostThreadMessage方式
  • Event方式,SetEvent、ResetEvent、WaitForMultipleObjects
  • 临界区
  • 信号量

子线程与主线程之间的异步、同步回调方式

借助windows窗口,在主线程中注册回调事件,子线程通过postmessage方式发送给该窗口,从而实现消息通知。
实现方式如下:
1.在主线程中创建一个窗口,在窗口WndClass中回调函数设置指定的消息通知WM_USER_NOTIFY
伪代码如下:

Class MainSuperviseWnd {
   WNDCLASS wndclass;
   wndclass.lpfnWndProc=WndProc; //定义窗口处理函数
   wndclass.hInstance=hInstance; //hInstance为主线程句柄,或用module{0}代替
   if(!RegisterClass(&wndclass)) //如果注册失败 发出警告
   	  return FALSE;
   hwnd=CreateWindow( lpszClassName,
   					lpszTitle,
  	 				WS_OVERLAPPEDWINDOW,
   					0,0,0,0,NULL,NULL,
   					hInstance,
   					this);
};

其中回调函数为:

UINT CALLBACK WNDPROC(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam){
	switch(msg):
	case WM_USER_NOTIFY:
		{
			// OnDispatch Method
			OnDispatch(wParam, lParam);
		}
}

在子线程中使用异步分发函数

void DispatchOnMain(){
	::PostMessage(hWnd, WM_USER_NOTIFY, wParam, lParam);
}

或者在子线程中使用同步分发函数并设置超时时间

void DispatchSyncOnMain() {
	::SendMessage(hWnd, WM_USER_NOTIFY, wParam, lParam);
	::WaitForSingleObject(
}

当然,跨线程调用除了同步或异步执行一些常见操作外,还可以带上lambd表达式

异步或同步跨线程执行回调函数

比较理想的方式是使用QT的emit\signal\slot方式,相对来说线程安全也十分灵活,而且设置的参数是可变的。但是在一般win32应用上,要复制QT的实行难度比较大,我们选择轻量级的实现方式。

一般来说,线程上的函数调用是在栈上,lambda表示式作为闭包同样也在线程上,所以lambda表示如果要传递给其他线程,可以考虑借助堆来实现。
我们可以再SendMessage之前使用new方式在堆上创建一个闭包

void DispatchOnMain(const std::function<void(void)>& func){
	std::function<void(void)> *p = new std::function<void(void)>(func);
	::PostMessage(hwnd, WM_USER_NOTIFY,wParam,(LPVOID)p);
}

相对应的,在消息处理函数中处理回调函数

void OnDispatch(WPARAM wParam, LPARAM lParam){
	std::function<void(void)> *block = reinterpret_cast<std::function<void(void)>>(lParam);
	if(block){
		(*block)();
		delete block;
	}
}

以上及实现了子线程同步回调函数到主线程中的方式。
相对于ios的GCD方式而言,该方法比较简陋,而且也只有一种同步方式,当时可以适当拓展。比如使用广播的方式来通知所有当前能够处理WM_USER_NOTIFY的消息窗口。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值