一.线程间数据通信 系统从进程的地址空间中分配内存给线程栈使用。新线程与创建它的线程在相同的进程上下文中运行。因此,新线程可以访问进程内核对象的所有句柄、进程中的所有内存以及同一个进程中其他所有线程的栈。这样一来,同一个进程中的多个线程可以很容易的相互通信。 到目前为止,将数据从一个线程传到另一个线程的惟一方法是在创建线程时传递给新线程一个指针参数(LPVOID lpParam)。参数 lpParam 为 LPVOID 指针类型,我们可在其中存储普通的数值(size 为平台地址总线宽度),也可以存放指向某个数据结构(struct或 class)的地址。在新线程函数中,解引用时需要强制类型转换回原类型,以进行正确的访问。 以下代码段演示了一个典型的多线程场景。 // A typical multithread scene DWORD WINAPI FirstThread(PVOID lpParam) { // Initialize a stack-based variable int x = 0; DWORD dwThreadID; // Create a new thread. HANDLE hThread = CreateThread(NULL, 0, SecondThread, (LPVOID)&x, 0, &dwThreadID); // We don't reference the new thread anymore, // so close our handle to it. CloseHandle(hThread); // Our thread is done. // BUG:our stack will be destroyed, // but SecondThread might try to access it. return 0; } DWORD WINAPI SecondThread(LPVOID lpParam) { // Do some lengthy processing here. // ... // Attempt to access the variable on FirstThread's stack. // NOTE:This may cause an access violation - it depends on timing! *((int*)lpParam) = 5; // ... return 0; } 上述场景中,Window s 没有维持线程之间的“父子关系“,即父线程 FirstThread已经终止运行,而子线程 SecondThread 仍在继续运行。以上父子关系只是为了一种解说上的方便,实际上FirstThread和SecondThread具有相同的优先级(默认是 normal),因此它们“同时”执行。这样,FirstThread 在开辟 SecondThread 后,不等SecondThread 运行至代码*((int*)lpParam) = 5;即可能退出。FirstThread 栈上的自动变量 x 已销毁,而 SecondThread 试图去访问之,将导致 Access Violation。这是多线程编程中新手常犯的错误。 解决以上问题,大概有以下三种方案。 (1)让创建线...