线程同步

当处理多线程操作系统时,会存在对个线程试图访问同一个资源的情况,为了保证获得稳定的结果,必须使用同步来协调各个线程的活动。

临界区域(临界区域)

有四个函数用于临界区域。要使用这些函数,您必须定义一个临界区域对象,这是一个型态为CRITICAL_SECTION的整体变量。例如:

CRITICAL_SECTION cs ;
        

这个CRITICAL_SECTION数据型态是一个结构,但是其中的字段只能由Windows内部使用。这个临界区域对象必须先被程序中的某个线程初始化,通过呼叫:

InitializeCriticalSection (&cs) ;
        

这样就建立了一个名为cs的临界区域对象。该函数的在线辅助说明包含下面的警告:「临界区域对象不能被移动或者复制,程序也不能修改该对象,但必须在逻辑上把它视为不透明的。」这句话,可以被解释为:「不要干扰它,甚至不要看它。」

当临界区域对象被初始化之后,线程可以通过下面的呼叫进入临界区域:

EnterCriticalSection (&cs) ;
        

(在这两个函数之间处理全局变量)

在这时,线程被认为「拥有」临界区域对象。两个线程不可以同时拥有同一个临界区域对象,因此,如果一个线程进入了临界区域,那么下一个使用同一临界区域对象呼叫EnterCriticalSection的线程将在函数呼叫中被暂停(阻塞并停止运行)。只有当第一个线程通过下面的呼叫离开临界区域时,函数才会传回控制权:

LeaveCriticalSection (&cs) ;
        

这时,在EnterCriticalSection呼叫中被停住的那个线程将拥有临界区域,其函数呼叫也将传回,允许线程继续执行。

当临界区域不再被程序所需要时,可以通过呼叫

DeleteCriticalSection (&cs) ;
        

将其删除,该函数释放所有被配置来维护此临界区域对象的系统资源。

 

 

从WinCE3.0开始,存在一个对TryEnterCriticalSection函数的支持,这个函数允许一个线程验证一个关键区是否可用,如可用,这个线程拥有这个关键区,否则,这个线程去处理其他事物。EnterCritialSection 总是使一个线程在关键区可用之前处于阻塞状态。

 

 

 互斥对象

临界区域的一个限制是它们只能用于在同一程序内的线程之间的协调。但是在某些情况下,您需要协调两个不同程序对同一资源的共享(如共享内存等)。在此其况下不能使用临界区域,但是可以使用一种被称为「互斥对象(mutex object)」的技术。「mutex」是个合成字,代表「mutual exclusion(互斥)」,它在这里精确地表达了我们的目的。我们想防止一个程序的线程在更新数据或者使用共享内存与其它资源时被中断。

CreatMutex();

WaitForSingleObject();

The WaitForSingleObject function can wait for the following objects:

  • Event
  • Mutex
  • Semaphore
  • Process
  • Thread
BOOL ReleaseMutex( 
  HANDLE hMutex 
);
临界区域(关键区) 和 互斥对象 的区别:
关键区只能用于单个的进程中的两个线程之间的同步,而互斥体能够跨越进程的边界,可用于两个进程间线程的同步。关键区和互斥对象
相比一个优点是关键区比互斥对象快。
信号量
信号量对象是由一个计数器的互斥对象。如果希望限制访问一个资源的线程的数量,
信号量是很有用的。
每当一个线程申请访问互斥对象保护的资源时,当前线程就调用内核的等待函数,
这使得信号量对象检查其当前计数器值,如果大于零,内核就发出申请线程可以进
入的信号;如果等于零,那么申请线程就处于挂起状态。
 
CreatSemaphore()函数。
WaitForSingleObject();等待信号量大于0;
ReleaseSemaphore();释放信号量。
CloseHandle();关闭信号量;
ReleaseSemaphore()的另一种用法:在应用程序的初始化过程中,首先
产生一个计数器值为0的信号量对象,这将阻止所有的应用程序访问受保护的资源
,当应用程序完成初始化后,再使用ReleaseSemaphore(),将计数器的值
设置为最大允许值,以允许正常访问受保护资源。
互锁事件:
互锁函数用于同步多个线程间共享变量的访问。它可以防止一个线程在增加、减少
或检查一个变量的值时被另一个线程抢先。
事件:事件对象是一种人造的信号,用于通知同一个进程或不同进程的某个线程完
成某个任务或出现了某个事件,以便线程下一步完成这个任务或相应这个事件。
局部定义的事件只能用于进程内,而全局定义的事件对象可以允许进程间的同步。
CreateEvent;OpenEvent;SetEvent;ResetEvent;PulseEvent;
WaitForSingleObject;CloseHandle;
点对点消息队列
WinCE支持三种类型的消息队列:
1.用于接收用户事件,并使其与窗口过程通信,这种队列与想SendMessage;
GetMessage这样的函数相关联。
2.MSMQ API关联。它提供了一种在网络连接的计算机间发送数据的机制,包括
MQCreatQueue;MQBeginTransaction;MQSendMessage等。
3. 点对点消息队列。它服务于进程间通信(IPC),用于从一个进程向另一个进程
发送数据。
点对点消息的用法:一个应用程序创建一个全局命名的消息队列,然后等待
接收来自这个队列的消息;第二个进程打开这个消息队列的句柄,然后向队列
发送消息;当队列收到消息时唤醒等待接收的线程接收消息。
CreateMsgQueue;
OpenMsgQueue;
CloseMsgQueue;
ReadMsgQueue;
WriteMsgQueue;
GetMsgQueueInfo;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值