• 线程间通信与同步


     
    线程间通信的两个基本问题是互斥和同步。
     
    同步:一个线程的执行依赖于另一个线程的消息。
    互斥:对共享资源的排他性,一个线程必须等待别的线程释放公共资源之后才能继续执行。
     
    同步机制(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( .. )
     
     
    #线程死锁的例子
    主线程
    辅线程                                                           改进后的辅线程
          
     
    此时程序会进入死锁而死掉, 两个线程互相等待对方释放临界区。
     
     
     
     
     
     
     
     
     
     





  • 相关阅读:
    安装CentOS7重启后提示License information
    使用VMware 安装Linux CentOS7
    VS 2015相当不错的功能:C#交互窗口
    未能正确加载“Microsoft.VisualStudio.Editor.Implementation.EditorPackage”包
    RabbitMQ service is already present
    RabbitMQ安装后不能运行 Error: unable to connect to node nodedown
    〖Demo〗-- 计算器
    〖Demo〗-- HAproxy配置文件操作
    〖Python〗-- 模块系列(二)
    〖Python〗-- 模块系列(一)
  • 原文地址:https://www.cnblogs.com/fysola/p/4818060.html
Copyright © 2020-2023  润新知