创建两个线程thread1 和thread2,由thread1发消息给thread2,消息的内容是一个结构体
Struct A{
Int ..;
Char ..;
}
2收到消息后要告知1以收到,最后1要发布消息证明2已收到。
思路:1.创建线程,要知道createthread函数怎么使用(其中还要理解句柄的含义和用途);
2.创建后每个线程要实现各自的功能,可以使用event控制线程之间的执行过程。
3.将结构体作为消息时要注意消息的格式,和MSG函数的结构。
具体代码如下:
#include <stdio.h>
#include <windows.h>
//变量的定义
HANDLE hthread1;//定义全局变量 句柄1和句柄1,注意句柄的定义是以h开头的单词。
HANDLE hthread2;
HANDLE hstartevent;//定义事件句柄
unsigned nThreadID1; //定义线程1和2的线程ID
unsigned nThreadID2;
//要传送的结构体
struct MyData{
int num;
char name;
};
struct MyData MyData1={1,'a'};//定义MyData类型的变量MyData1,并赋初值。
struct MyData *pMyData1=&MyData1;//定义一个MyData类型的指针pMyData1,并让她指向//已经赋好初值的结构体MyData1
//编写线程的功能函数,让它们实现题目中的要求
DWORD WINAPI thread1(LPVOID IpParam){
UINT mymessage =0; //定义一个消息
printf("Thread 1 launched\n");//此时1已被创建,向屏幕上输出语句 3
SetThreadPriority(hthread1,THREAD_PRIORITY_ABOVE_NORMAL);//为1设置优先级4
printf("priority of thread1 is %d\n",GetThreadPriority(hthread1));//获得优先级并输出5
/*发送消息,注意,消息是发送到消息队列中的,所以我们要等待对方的消息队
列创建完成。*/
WaitForSingleObject(hstartevent,INFINITE);//等收方确定已经创建好消息队列的信号。1
printf("the message is %d and %c\n",MyData1.num,MyData1.name);//发布要发送消 4
//息的内容
PostThreadMessage(nThreadID2,mymessage,(WPARAM)pMyData1,(LPARAM)NULL);//发消息.5
WaitForSingleObject(hstartevent,INFINITE);//等待收方发送确定已经收到消息的信号 6
printf("thread2 have got the message!\n");/* 发布2真的已经收到消息了 最终
return(0);
}
DWORD WINAPI thread2(LPVOID IpParam){
MSG msg;//定义一个MSG结构的消息,注意MSG是一个结构体
struct MyData *pData;//定义一个用于承载消息的指针,post时我是用指针的形式到我//要发送的结构体的,所以此处也要用指针接收。
printf("Thread 2 launched\n"); 6
SetThreadPriority(hthread2,THREAD_PRIORITY_LOWEST); 7
printf("priority of thread2 is %d\n",GetThreadPriority(hthread2)); waitforsingleobject函数8
//接受消息
PeekMessage(&msg,(HWND)NULL,(UINT)NULL,(UINT)NULL,(UINT)PM_NOREMOVE);//创建一个消息队列后2
SetEvent(hstartevent);//设置hstartevent为有信号状态,用于通知发方已经创建好消息队列。3返回1
GetMessage(&msg,0,0,0);//从消息队列中取消息并放于指定结构 7
if (ssage==0)//如果得到的结构体中的message值为我设置的初始值,也就是说
//收到1发送的消息了 8
{
pData=msg.wParam;//就把post过来的指针传给一个新的指针
}
printf("the message i have got is: %d and %c\n",pData->num,pData->name);//发布已收到的消息。9
SetEvent(hstartevent);//设置hstartevent为有信号状态,用于通知发放已经收到消息。10返回6
return(0);
}
int main()
{
hstartevent=CreateEvent(NULL,FALSE,FALSE,NULL); //自动恢复为无信号状态,初始无无信号状态
hthread1=CreateThread(NULL,0,thread1,NULL,0,&nThreadID1); 1
hthread2=CreateThread(NULL,0,thread2,NULL,0,&nThreadID2); 2
WaitForSingleObject(hthread1,INFINITE); //等待thread1执行结束。
WaitForSingleObject(hthread2,INFINITE);//等待thread2执行结束。
//关闭所有句柄。
CloseHandle(hthread1);
CloseHandle(hthread2);
CloseHandle(hstartevent);
}
函数说明:
1 SetThreadPriority函数的参数有两个,第一个是要设置函数的句柄,如要设置thread1,则此处要写thread1的句柄---- hthread1. 第二个是要设置的优先级的等级,有几个不同的等级可以选择,此处我们设置1的优先级比一般的高:THREAD_PRIORITY_ABOVE_NORMAL。
2的优先级低:THREAD_PRIORITY_LOWEST。
2 GetThreadPriority函数的参数只有一个即线程的句柄。
3 WaitForSingleObject函数的参数有两个,一个是句柄,一个是等待的时间,如WaitForSingleObject(hstartevent,INFINITE)就是要一直等待startevent这个事件有信号。
4 PostThreadMessage函数的参数有四个,第一个为消息发送目的地的ID。第二个是消息的类型,可以理解为消息的名称,是UINT类型的,在功能函数开始时要定义它。第三和第四个参数都是附加消息信息,是WPARAM或者LPARAM类型的,在此题目中,我利用指向结构体的指针来传送这条消息。
5 PeekMessage函数用于检查线程的消息队列,有5个参数,第一个是接收消息信息的MSG结构指针,此处定义msg就是MSG结构的,用于接收消息,要求用指针所以要用&符号。第二三四参数设为空即可。最后一个表示peek后,是否将消息从对列中删除。
6 GetMessage用于从消息队列中取消息,此函数可取得与指定窗口联系的消息和由PostThreadMesssge寄送的线程消息。此函数接收一定范围的消息值。GetMessage不接收
属于其他线程或应用程序的消息。获取消息成功后,线程将从消息队列中删除该消息。函数会一直等待直到有消息到来才有返回值。第一个参数既是指向MSG结构的指针,该结构从线程的消息队列里接收消息信息。
7 CreateEvent用于创建一个事件,第二个参数说明这个事件是用手动还是自动复原,如果是TRUE,那么必须用ResetEvent函数来手工将事件的状态复原到无信号状态。如果设置为FALSE,当事件被一个等待线程释放以后,系统将会自动将事件状态复原为无信号状态。第三个参数是指定事件对象的初始状态。如果为TRUE,初始状态为有信号状态;否则为无信号状态。
8 CreateThread用于创建一个线程,第三个参数指向线程函数的指针,形式:@函数名,函数名称没有限制,但是必须以下列形式声明:
DWORD WINAPI ThreadProc (LPVOID pParam) ,格式不正确将无法调用成功。最后一个参数是:保存新线程的id。
创建线程的过程用黄底的标号写出
传送消息的过程用红底的标号写出
绿为最终结果。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论