穿紧身裤子跑步可以吗:VC 线程间通信

来源:百度文库 编辑:偶看新闻 时间:2024/05/03 02:54:01

1.使用全局变量(窗体不适用)
     实现线程间通信的方法有很多,常用的主要是通过全局变量、自定义消息和事件对象等来实现的。其中又以对全局变量的使用最为简洁。该方法将全局变量作为线程监视的对象,并通过在主线程对此变量值的改变而实现对子线程的控制。
     由于这里的全局变量需要在使用它的线程之外对其值进行改变,这就需要通过volatile关键字对此变量进行说明。使用全局变量进行线程通信的方法非常简单,通过下面给出的示例代码能够对其有一个基本的认识。

 

2.利用自定义消息(可适用于窗体)

    全局变量在线程通信中的应用多用在主线程对子线程的控制上,而从子线程向主线程的信息反馈则多采用自定义消息的方式来进行。这里对自定义消息的使用同使用普通自定义消息非常相似,只不过消息的发送是在子线程函数中进行的。该方法的主体是自定义消息,应首先定义自定义消息并添加对消息的响应代码。

      用PostMessage()或SendMessage()消息传递函数.


3.使用事件内核对象(相当好用)
    利用事件(Event)内核对象对线程的通信要复杂些,主要通过对事件对象的监视来实现线程间的通信。事件对象由CreateEvent()函数来创建,具有两种存在状态:置位与复位,分别由SetEvent()和ResetEvent()来产生。事件的置位将通过WaitForSingleObject()或WaitForMultipleObjects()之类的通知等待函数继续执行。

// 事件句柄
HANDLE hEvent = NULL;

UINT ThreadProc7(LPVOID pParam)
{
                 while(true)
                 {
                               // 等待事件发生
                               DWORD dwRet = WaitForSingleObject(hEvent, 0);
                               // 如果事件置位则退出线程,否则将继续执行
                               if (dwRet == WAIT_OBJECT_0)
                                            break;
                               else
                               {
                                            Sleep(2000);
                                            AfxMessageBox("线程正在运行!");
                               }
                 }
              
                 AfxMessageBox("线程终止运行!");
                 return 0;
}
……
void CSample06View::OnEventStart()
{
                 // 创建事件  
                 hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
              
                 // 启动线程
                 AfxBeginThread(ThreadProc7, NULL);
}

void CSample06View::OnEventEnd()
{
                 // 事件置位
                 SetEvent(hEvent);            
}

    上面这段代码展示了事件对象在线程通信中的作用。在创建线程前首先创建一个事件对象hEvent,这里CreateEvent()函数所采用的四个参数分别表示句柄不能被继承、事件在置位后将由系统自动进行复位、事件对象初始状态为复位状态和不指定事件名。在创建的子线程中使用WaitForSingleObject()对hEvent进行监视。WaitForSingleObject()的函数原型为:

                 DWORD WaitForSingleObject(
                               HANDLE hHandle,                             //等待对象的句柄
                               DWORD dwMilliseconds           //超过时间间隔
                 );

    函数将在hHandle对象有信号时或是在等待时间超出由dwMilliseconds设定的超时时间间隔返回。其返回值可以为WAIT_ABANDONED、WAIT_OBJECT_0和WAIT_TIMEOUT,分别表示被等待的互斥量(Mutex)对象没有被释放、等待的对象信号置位和超时。通过对返回值的判断可以区分出引起WaitForSingleObject()函数返回的原因。在本例中只关心WAIT_OBJECT_0的返回值,当通过SetEvent()将hEvent置位后即可使WaitForSingleObject()立即返回并通过跳出循环而结束线程。