操作系统中存在的两种调度单位是进程和线程,现成比进程更小,是调度的基本单位,但是进程拥有自己独立的系统资源,而线程不拥有这些资源。就好比是一个一条马路上有很多辆马车,而马车由好几匹马来拉动。在这里,马车就是进程,马就是线程。进程通信是讲的比较多的,很多教科书上也有,包括下面几种:
1.管道
2.信号(系统内的一些信号,复杂,与信号量不同)
3.消息队列
4.共享内存
5.信号量(进程线程同步互斥的方法)
6.套接字
对于线程来说的话,目前了解是三种
1.信号量
2.消息队列,消息邮箱(windows下的反映是Message)
3.事件(windows下event)
我想主要说的是消息队列,我是如何用Message来做的。
Message的主要函数是主要是一下函数
PostThreadMessage,PostMessage,SendMessage,PeekMessage,GetMessage,目前了解的是这几个函数。
PostMessage主要是对具体的窗口进行消息的发送,消息发送以后,不等待消息返回。而SendMessage则是需要等待消息结果返回。两者,PostMessage是异步的,而SendMessage是同步的。
两者原型:
LRESULT SendMessage(
HWND hWnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam
);
BOOL PostMessage(
HWND hWnd,
UINT Msg,
WPARAM wParam,
LPARAM lParam
);
参数一样,但是处理方式不一样。MSDN里是这么说的,PostMessage是将消息加入消息队列,然后由( DispatchMessage)将消息派发出去,而SendMessage的原理是调用了windows的函数,既然是调用了函数,肯定有一个返回的情况,所以SendMessage会一直阻塞,然后等待消息处理结果返回。如果只是用的话没必要去了解这两个函数的内部实现源码什么的。
这里的4个参数,其中第三个,第四个一般是0,
SendMessage(handle1,msg,0,0)
因为用消息一般只知道消息的话就可以了,但是在我的应用里,我却用到了第三个和第四个参数。其中第四个参数是一个数据指针,第三个参数是放的数据的大小,这样通过message可以将附加数据发送给指定的窗口,然后指定窗口将数据取出后进行处理。
消息需要进行映射,也就是我们看到的
BEGIN_MESSAGE_MAP(CpassApp, CWinApp)
ON_COMMAND(ID_HELP, CWinApp::OnHelp)
END_MESSAGE_MAP()
第一个CpassApp是自己的类,CWinApp是基类,ID_HELP是标示符,OnHelp是具体函数,和相关按钮等关联函数的处理相似。函数内的接受数据也必须是
WPARAM wParam,
LPARAM lParam
PostThreadMessage应用的话,可以更广一些,他可以针对具体线程,而不拘泥于MFC。
BOOLPostThreadMessage(
DWORD idThread,
UINT Msg,
WPARAM wParam,
LPARAM IParam
);
其中第一个参数不同,指的是线程的ID。通过这个函数也是会将消息放入消息队列中,然后根据事先定义的消息,接收线程会接收到数据。具体的接收数据是通过:PeekMessage,GetMessage。
GetMessage从消息队列中取出消息,然后将消息从队列中删除掉,而PeekMessage则不同,函数PeekMesssge是以查看的方式从系统中获取消息,可以不将消息从系统中移除,是非阻塞函数。
BOOL GetMessage(LPMSG lpMsg,HWND hWnd,UINT wMsgFilterMin,UINT wMsgFilterMax)
第一个是最重要的msg,需要实现定义一个msg,
MSG msg
GetMessage(&msg, NULL, 0, 0)
switch(msg.message){
case MSG_SEND:
break;
default:
break;
这是通过switch函数根据消息的类型进行处理。
差不多自己知道就这些,希望后面可以继续总结~