您的位置:首页 > 其它

线程间通信与同步

2015-09-18 00:24 211 查看
线程间通信的两个基本问题是互斥和同步。
同步:一个线程的执行依赖于另一个线程的消息。互斥:对共享资源的排他性,一个线程必须等待别的线程释放公共资源之后才能继续执行。
同步机制(Win32中):事件,信号量,互斥量,临界区
各种同步方式:#全局变量win32多线程通信的最方式,但用全局变量同步会有两个弊端,应该避免>主线程没有进入休眠状态,依然会消耗CPU资源>如果主线程优先级比ThreadFunc高,则全局变量无法在ThreadFunc中被改变,这样线程无法得到通知
#事件由于event对象属于内核对象,则一个进程的线程可以控制另一进程中的线程运行
#临界区只能用来同步本进程内的线程,而不可用来同步多个进程内的线程
#临界区的使用流程>定义一个临界区结构变量CRITICAL_SECTION g_cs;>初始化临界区InitializeCriticalSection( &g_cs );>进入线程,在线程中进入临界区,离开临界区UINT ThreadProc10 ( LPVOID pParam ) {//进入临界区EnterCriticalSection( &g_cs );//开始使用共享资源g_var = 100; // g_var 为全局共享资源//离开临界区LeaveCriticalSection( &g_cs );
#使用临界区注意事项>每个共享资源使用一个CRITICAL_SECTION变量(临界区结构变量)>不要长时间运行关键代码,每一个关键代码段长时间运行时,其他线程就会进入等待状态,这会降低应用程序的性能。>如果需要同时访问多个资源,则可能连续调用EnterCriticalSection>Critical Section不是OS核心对象,如果进入临界区的线程死掉,将无法释放资源
#互斥(Mutex) Mutex是系统核心对象,可跨进程访问>创建互斥量HANDLE hMutex = CreateMutex ( .. LPCTSTR lpName )>释放互斥量BOOL WINAPI ReleaseMutex (HANDLE hMutex )>使用互斥量的一般流程void UpdateResource(){ WaitForSingleObject (hMutex) ;
... // do somthing here
ReleaseMutex( hMutex );
}
#互斥与临界区的异同>互斥对象的运行速度比临界区的关键代码慢>不同进程中的多个线程能够访问单个互对象>使用互斥时,线程在等待访问资源时可以设定一个超时值





#信号量的特点和用途>信号量也可以通过名字跨进程使用>如果当前资源的数量大于0,则信号量有效>如果当前资源数量是0,则信号量无效>系统决不允许当前资源的数量为负值>当前资源数量绝不能大于最大资源量
#信号量相关函数>创建信号量 CreateSemaphore ( .. PCTSTR pszName) ;>释放信号量 ReleaseSemaphore ( .. )>打开信号量 OpenSemaphore ( ... )
#互锁访问使用方式 InterlockedExchangeAdd(&globalVar , 1); //可以让全局共享变量 globalVar + 1 以原子操作方式实现>优点:互锁访问控制速度非常快>缺点:资源类型只能是单一变量。如果资源比较复杂,仍然要使用临界区或互斥
#可等待定时器可等待定时器是一个内核对象,在某个时间按某规定的时间间隔发出自己的信号通知的内核对象。>创建可等待定时器CreateWaitableTimer ( ... PCTSTR pszName--信号名称 )>设置可等待定时器SetWaitableTime( .. )>取消可等待定时器CancelWaitableTimer ( .. )>打开可等待定时器OpenWaitableTimer( .. )

#线程死锁的例子主线程


辅线程 改进后的辅线程








此时程序会进入死锁而死掉, 两个线程互相等待对方释放临界区。

来自为知笔记(Wiz)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: