//转载完整的例子 /* * Worker.cpp * * Sample code for "Multithreading Applications in Win32" * This is from Chapter 14, Listing 14-3 * * Demonstrate using worker threads that have * their own message queue but no window. */
// This thread has to wait for the new thread // to init its globals and msg queue. WaitForSingleObject(ghEvent, INFINITE);
// The only place in the book we get to use // the thread ID! char *szText = strdup("Thank you for buying this book.\n"); PostThreadMessage(tid, WM_JOB_PRINT_AS_IS, NULL, (LPARAM)szText);
szText = strdup("Text is easier to read forward.\n"); PostThreadMessage(tid, WM_JOB_PRINT_REVERSE, NULL, (LPARAM)szText);
szText = strdup("\nLOWER CASE IS FOR WHISPERING.\n"); PostThreadMessage(tid, WM_JOB_PRINT_LOWER, NULL, (LPARAM)szText);
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
return 0; }
VOID CALLBACK TimerFunc( HWND hwnd, // handle of window for timer messages UINT uMsg, // WM_TIMER message UINT idEvent, // timer identifier DWORD dwTime ) // current system time { UNREFERENCED_PARAMETER(hwnd); UNREFERENCED_PARAMETER(uMsg);
/* * Call a function to do something that terminates * the thread with ExitThread instead of returning. */ unsigned WINAPI ThreadFunc(LPVOID n) { UNREFERENCED_PARAMETER(n);
MSG msg;
// This creates the message queue. PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE);
SetEvent(ghEvent);
// We'll run for two seconds SetTimer(NULL, NULL, 2000, (TIMERPROC)TimerFunc);
while (GetMessage(&msg, NULL, 0, 0)) { char *psz = (char *)msg.lParam; switch(msg.message) { case WM_JOB_PRINT_AS_IS: printf("%s", psz); free(psz); break; case WM_JOB_PRINT_REVERSE: printf("%s", strrev(psz)); free(psz); break; case WM_JOB_PRINT_LOWER: printf("%s", _strlwr(psz)); free(psz); break; default: DispatchMessage(&msg); } }
return 0; }
下面是这个例子中用到的一个用于断言的头文件 /* * MtVerify.h * * Error handling for applications in * "Multitheading Applications in Win32" * * The function PrintError() is ed as __inline so that it can be * included from one or more C or C++ files without multiple definition * errors. For the examples in this book, this works fine. * To use the PrintError() in an application, it should be taken out, * placed in its own source file, and the "__inline" declaration removed * so the function will be globally available. */
代码都整理好了。/* * Worker.cpp * * Sample code for "Multithreading Applications in Win32" * This is from Chapter 14, Listing 14-3 * * Demonstrate using worker threads that have * their own message queue but no window. */
int main(VOID) { HANDLE hThread; unsigned tid; // Give the new thread something to talk // to us with. ghEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
hThread = (HANDLE)_beginthreadex(NULL, 0, ThreadFunc, 0, 0, &tid); MTVERIFY(hThread); // This thread has to wait for the new thread // to init its globals and msg queue. WaitForSingleObject(ghEvent, INFINITE); // The only place in the book we get to use // the thread ID! char *szText = strdup("Thank you for buying this book.\n"); PostThreadMessage(tid, WM_JOB_PRINT_AS_IS, NULL,(LPARAM)szText); szText = strdup("Text is easier to read forward.\n"); PostThreadMessage(tid, WM_JOB_PRINT_REVERSE, NULL, (LPARAM)szText); szText = strdup("\nLOWER CASE IS FOR WHISPERING.\n"); PostThreadMessage(tid, WM_JOB_PRINT_LOWER, NULL, (LPARAM)szText); WaitForSingleObject(hThread, INFINITE); CloseHandle(hThread); return 0; }
VOID CALLBACK TimerFunc( HWND hwnd, // handle of window for timer messages UINT uMsg, // WM_TIMER message UINT idEvent, // timer identifier DWORD dwTime ) // current system time { UNREFERENCED_PARAMETER(hwnd); UNREFERENCED_PARAMETER(uMsg);
/* * Call a function to do something that terminates * the thread with ExitThread instead of returning. */ unsigned WINAPI ThreadFunc(LPVOID n) { UNREFERENCED_PARAMETER(n);
MSG msg;
// This creates the message queue. PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE);
SetEvent(ghEvent);
// We'll run for two seconds SetTimer(NULL, NULL, 2000, (TIMERPROC)TimerFunc);
while (GetMessage(&msg, NULL, 0, 0)) { char *psz = (char *)msg.lParam; switch(msg.message) { case WM_JOB_PRINT_AS_IS: printf("%s", psz); free(psz); break; case WM_JOB_PRINT_REVERSE: printf("%s", strrev(psz)); free(psz); break; case WM_JOB_PRINT_LOWER: printf("%s", _strlwr(psz)); free(psz); break; default: DispatchMessage(&msg); } }
return 0; }
下面是这个例子中用到的一个用于断言的头文件 /* * MtVerify.h * * Error handling for applications in * "Multitheading Applications in Win32" * * The function PrintError() is ed as __inline so that it can be * included from one or more C or C++ files without multiple definition * errors. For the examples in this book, this works fine. * To use the PrintError() in an application, it should be taken out, * placed in its own source file, and the "__inline" declaration removed * so the function will be globally available. */
m_pCalculateThread->PostThreadMessage(WM_CALCULATE,nAddend,NULL); ::PostMessage((HWND)(GetMainWnd()->GetSafeHwnd()),WM_DISPLAY,nTmpt,NULL);==============================
http://blog.ednchina.com/opencv2008/216706/message.aspx
* Worker.cpp
*
* Sample code for "Multithreading Applications in Win32"
* This is from Chapter 14, Listing 14-3
*
* Demonstrate using worker threads that have
* their own message queue but no window.
*/
#define WIN32_LEAN_AND_MEAN
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <process.h>
#include <string.h>
#include "MtVerify.h"
unsigned WINAPI ThreadFunc(void* p);
HANDLE ghEvent;
#define WM_JOB_PRINT_AS_IS WM_APP + 0x0001
#define WM_JOB_PRINT_REVERSE WM_APP + 0x0002
#define WM_JOB_PRINT_LOWER WM_APP + 0x0003
int main(VOID)
{
HANDLE hThread;
unsigned tid;
// Give the new thread something to talk
// to us with.
ghEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
hThread = (HANDLE)_beginthreadex(NULL,
0,
ThreadFunc,
0,
0,
&tid );
MTVERIFY(hThread);
// This thread has to wait for the new thread
// to init its globals and msg queue.
WaitForSingleObject(ghEvent, INFINITE);
// The only place in the book we get to use
// the thread ID!
char *szText = strdup("Thank you for buying this book.\n");
PostThreadMessage(tid, WM_JOB_PRINT_AS_IS, NULL, (LPARAM)szText);
szText = strdup("Text is easier to read forward.\n");
PostThreadMessage(tid, WM_JOB_PRINT_REVERSE, NULL, (LPARAM)szText);
szText = strdup("\nLOWER CASE IS FOR WHISPERING.\n");
PostThreadMessage(tid, WM_JOB_PRINT_LOWER, NULL, (LPARAM)szText);
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
return 0;
}
VOID CALLBACK TimerFunc(
HWND hwnd, // handle of window for timer messages
UINT uMsg, // WM_TIMER message
UINT idEvent, // timer identifier
DWORD dwTime ) // current system time
{
UNREFERENCED_PARAMETER(hwnd);
UNREFERENCED_PARAMETER(uMsg);
PostThreadMessage(GetCurrentThreadId(), WM_QUIT,0,0);
}
/*
* Call a function to do something that terminates
* the thread with ExitThread instead of returning.
*/
unsigned WINAPI ThreadFunc(LPVOID n)
{
UNREFERENCED_PARAMETER(n);
MSG msg;
// This creates the message queue.
PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE);
SetEvent(ghEvent);
// We'll run for two seconds
SetTimer(NULL, NULL, 2000, (TIMERPROC)TimerFunc);
while (GetMessage(&msg, NULL, 0, 0))
{
char *psz = (char *)msg.lParam;
switch(msg.message)
{
case WM_JOB_PRINT_AS_IS:
printf("%s", psz);
free(psz);
break;
case WM_JOB_PRINT_REVERSE:
printf("%s", strrev(psz));
free(psz);
break;
case WM_JOB_PRINT_LOWER:
printf("%s", _strlwr(psz));
free(psz);
break;
default:
DispatchMessage(&msg);
}
}
return 0;
}
下面是这个例子中用到的一个用于断言的头文件
/*
* MtVerify.h
*
* Error handling for applications in
* "Multitheading Applications in Win32"
*
* The function PrintError() is ed as __inline so that it can be
* included from one or more C or C++ files without multiple definition
* errors. For the examples in this book, this works fine.
* To use the PrintError() in an application, it should be taken out,
* placed in its own source file, and the "__inline" declaration removed
* so the function will be globally available.
*/
#pragma comment( lib, "USER32" )
#include <crtdbg.h>
#define MTASSERT(a) _ASSERTE(a)
#define MTVERIFY(a) if (!(a)) PrintError(#a,__FILE__,__LINE__,GetLastError())
__inline void PrintError(LPSTR linedesc, LPSTR filename, int lineno, DWORD errnum)
{
LPSTR lpBuffer;
char errbuf[256];
#ifdef _WINDOWS
char modulename[MAX_PATH];
#else // _WINDOWS
DWORD numread;
#endif // _WINDOWS
FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER
| FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
errnum,
LANG_NEUTRAL,
(LPTSTR)&lpBuffer,
0,
NULL );
wsprintf(errbuf, "\nThe following call failed at line %d in %s:\n\n"
" %s\n\nReason: %s\n", lineno, filename, linedesc, lpBuffer);
#ifndef _WINDOWS
WriteFile(GetStdHandle(STD_ERROR_HANDLE), errbuf, strlen(errbuf), &numread, FALSE );
Sleep(3000);
#else
GetModuleFileName(NULL, modulename, MAX_PATH);
MessageBox(NULL, errbuf, modulename, MB_ICONWARNING|MB_OK|MB_TASKMODAL|MB_SETFOREGROUND);
#endif
exit(EXIT_FAILURE);
}
MSG msg;
GetMessage(&msg,0,0,0);
switch(msg.message)
{
case WM_USER_MSG:
....
break;
default:
break;
}
#pragma comment(lib,"LIBCMT.LIB")
#pragma comment(lib,"ws2_32.lib")
HANDLE m_hEvent;
HANDLE m_h1;
unsigned long ThreadID1;
#define WM_USERMSG WM_USER+101
struct TagMsg
{
int ID;
char buf[100];
};
DWORD WINAPI ProcThread(void* lpParam)
{
SOCKET* s=(SOCKET*)lpParam;
TagMsg *Tmsg=new TagMsg;
memset(Tmsg,0,sizeof(TagMsg));
while(true)
{
char buf[100]={0};
strcpy(buf,"123sssssssss");
send(*s,buf,strlen(buf)+1,0);
Sleep(1000);
memcpy(Tmsg->buf,"1111111111hhh",sizeof(Tmsg->buf));
Tmsg->ID=100101;
::PostThreadMessage(ThreadID1,WM_USERMSG,0,(LPARAM)Tmsg);//*************//
}
}
DWORD WINAPI PrintThread(void* lpParam)
{ MSG msg;
TagMsg *pMsg=new TagMsg;
char *buf=new char[100];
while(true)
{
::GetMessage(&msg,0,0,0);//***************************//
switch(msg.message)
{
case WM_USERMSG:
{
memset(pMsg,0,sizeof(pMsg));
memcpy(pMsg,(TagMsg*)msg.lParam,sizeof(TagMsg));
printf("%d %s\n",pMsg->ID,pMsg->buf);
}
break;
default:
break;
}
}}
void main()
{
WORD wVersionRequested;
WSADATA wsaData;
wVersionRequested = MAKEWORD( 2, 2 ); WSAStartup( wVersionRequested, &wsaData ); SOCKET s=socket(AF_INET,SOCK_STREAM,0);
sockaddr_in si;
si.sin_port=::htons(4567);
si.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
si.sin_family=AF_INET; connect(s,(sockaddr*)&si,sizeof(sockaddr));
unsigned long ThreadID;
m_h1=CreateThread(NULL,0,PrintThread,NULL,0,&ThreadID1);
HANDLE m_h=CreateThread(NULL,0,ProcThread,(void*)&s,NULL,&ThreadID);
CloseHandle(m_h);
m_hEvent=CreateEvent(NULL,FALSE,FALSE,"sdd");
::WaitForSingleObject(m_hEvent,INFINITE);
closesocket(s);
WSACleanup();
}这是我自己今天才写的,你参考一下.
* Worker.cpp
*
* Sample code for "Multithreading Applications in Win32"
* This is from Chapter 14, Listing 14-3
*
* Demonstrate using worker threads that have
* their own message queue but no window.
*/
#define WIN32_LEAN_AND_MEAN
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <process.h>
#include <string.h>
#include "MtVerify.h"
unsigned WINAPI ThreadFunc(void* p);
HANDLE ghEvent;
#define WM_JOB_PRINT_AS_IS WM_APP + 0x0001
#define WM_JOB_PRINT_REVERSE WM_APP + 0x0002
#define WM_JOB_PRINT_LOWER WM_APP + 0x0003
int main(VOID)
{
HANDLE hThread;
unsigned tid; // Give the new thread something to talk
// to us with.
ghEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
hThread = (HANDLE)_beginthreadex(NULL,
0,
ThreadFunc,
0,
0,
&tid);
MTVERIFY(hThread); // This thread has to wait for the new thread
// to init its globals and msg queue.
WaitForSingleObject(ghEvent, INFINITE); // The only place in the book we get to use
// the thread ID!
char *szText = strdup("Thank you for buying this book.\n");
PostThreadMessage(tid, WM_JOB_PRINT_AS_IS, NULL,(LPARAM)szText); szText = strdup("Text is easier to read forward.\n");
PostThreadMessage(tid, WM_JOB_PRINT_REVERSE, NULL, (LPARAM)szText); szText = strdup("\nLOWER CASE IS FOR WHISPERING.\n");
PostThreadMessage(tid, WM_JOB_PRINT_LOWER, NULL, (LPARAM)szText); WaitForSingleObject(hThread, INFINITE); CloseHandle(hThread); return 0;
}
VOID CALLBACK TimerFunc(
HWND hwnd, // handle of window for timer messages
UINT uMsg, // WM_TIMER message
UINT idEvent, // timer identifier
DWORD dwTime ) // current system time
{
UNREFERENCED_PARAMETER(hwnd);
UNREFERENCED_PARAMETER(uMsg);
PostThreadMessage(GetCurrentThreadId(), WM_QUIT,0,0);
}
/*
* Call a function to do something that terminates
* the thread with ExitThread instead of returning.
*/
unsigned WINAPI ThreadFunc(LPVOID n)
{
UNREFERENCED_PARAMETER(n);
MSG msg;
// This creates the message queue.
PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE);
SetEvent(ghEvent);
// We'll run for two seconds
SetTimer(NULL, NULL, 2000, (TIMERPROC)TimerFunc);
while (GetMessage(&msg, NULL, 0, 0))
{
char *psz = (char *)msg.lParam;
switch(msg.message)
{
case WM_JOB_PRINT_AS_IS:
printf("%s", psz);
free(psz);
break;
case WM_JOB_PRINT_REVERSE:
printf("%s", strrev(psz));
free(psz);
break;
case WM_JOB_PRINT_LOWER:
printf("%s", _strlwr(psz));
free(psz);
break;
default:
DispatchMessage(&msg);
}
}
return 0;
}
下面是这个例子中用到的一个用于断言的头文件
/*
* MtVerify.h
*
* Error handling for applications in
* "Multitheading Applications in Win32"
*
* The function PrintError() is ed as __inline so that it can be
* included from one or more C or C++ files without multiple definition
* errors. For the examples in this book, this works fine.
* To use the PrintError() in an application, it should be taken out,
* placed in its own source file, and the "__inline" declaration removed
* so the function will be globally available.
*/
#pragma comment( lib, "USER32" )
#include <crtdbg.h>
#define MTASSERT(a) _ASSERTE(a)
#define MTVERIFY(a) if (!(a)) PrintError(#a,__FILE__,__LINE__,GetLastError())
__inline void PrintError(LPSTR linedesc, LPSTR filename, int lineno, DWORD errnum)
{
LPSTR lpBuffer;
char errbuf[256];
#ifdef _WINDOWS
char modulename[MAX_PATH];
#else // _WINDOWS
DWORD numread;
#endif // _WINDOWS
FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER
| FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
errnum,
LANG_NEUTRAL,
(LPTSTR)&lpBuffer,
0,
NULL );
wsprintf(errbuf, "\nThe following call failed at line %d in %s:\n\n"
" %s\n\nReason: %s\n", lineno, filename, linedesc, lpBuffer);
#ifndef _WINDOWS
WriteFile(GetStdHandle(STD_ERROR_HANDLE), errbuf, strlen(errbuf), &numread, FALSE );
Sleep(3000);
#else
GetModuleFileName(NULL, modulename, MAX_PATH);
MessageBox(NULL, errbuf, modulename, MB_ICONWARNING|MB_OK|MB_TASKMODAL|MB_SETFOREGROUND);
#endif
exit(EXIT_FAILURE);
}
这段代码中涉及了线程之间控制的消息和事件的使用,比如消息的截获,用PeekMessage,GetMessage, 事件的等待来挂起线程WaitForSingleObject(...).线程消息的传递PostThreadMessage,这些都是常用的线程之间控制和同步和相互通知的方法