2014年3月

使用关键段CS处理线程同步问题时,可以实现子线程子线程之间的互斥,由于关键段线程所有权的问题,不能够实现主线程与子线程之间的同步,本文介绍时间Event来处理主线程与子线程的同步问题。

一、事件Event
事件Event实际上是内核对象,下面是一些常用函数:
1、CreateEvent:创建事件

HANDLECreateEvent(
 LPSECURITY_ATTRIBUTESlpEventAttributes,
 BOOLbManualReset,
 BOOLbInitialState,
 LPCTSTRlpName
);

第一个参数表示安全性,一般传入NULL
第二个参数确定事件是手动置位还是自动置位,TRUE表示自动置位,FALSE表示手动置位;如果是自动置位,WaitForSingleObject()结束后自动调用ResetEvent()使事件变成未触发状态;
第三个参数表示初始化状态,FALSE表示创建后是为触发的;
第四个参数表示事件的名称,NULL表示匿名事件。

- 阅读剩余部分 -

首先从一个简单的例子开始这部分内容,主线程启动10个线程,并将子线程的序号作为参数变量传递给线程函数。子线程接收参数后,依次sleep(50),nNum++,sleep(0),最终输出线程序号和全局变量。我们希望线程序号不重复,且全局变量的输出必须递增

一、分析
1、主线程创建子线程并创建一个指向变量地址的指针作为参数,由于线程启动需要一定时间,所以要等指针传入子线程,待子线程保存序号后才能递增序号值,启动下一线程。——主线程和子线程同步;
2、子线程之间需要互斥地改动和访问全局变量,全局变量要实现递增。——子线程之间的互斥。

- 阅读剩余部分 -

网站每天需要统计访客人数,我们用线程模拟访客,线程执行一次,访客人数变量自增,程序最后输出访客人数。我们会发现实际线程数与统计的访客数不一样!由此引出线程的原子操作。

首先是一个示例,输出为实际次数和统计次数,程序循环20次:

#include <stdio.h>
#include <process.h>
#include <windows.h>
volatile long Logincount;                //登录数
unsigned int _stdcall Fun(void* pm);    //线程函数
int main()
{
    int i,j=20;
    while(j--)
    {
        Logincount=0;
        HANDLE handle[50];
        for(i=0;i<50;i++)
            handle[i]=(HANDLE)_beginthreadex(NULL,0,Fun,NULL,0,NULL);
        WaitForMultipleObjects(50,handle,TRUE,INFINITE);
        printf("实际次数:%d、统计次数:%d\n",50,Logincount);
    }
    return 0;
}
unsigned int _stdcall Fun(void* pm)
{
    Sleep(50);
    Logincount++;
    Sleep(50);
    return 0;
}

- 阅读剩余部分 -