美文网首页
windows线程同步

windows线程同步

作者: jiangxueqiao | 来源:发表于2017-05-02 18:01 被阅读0次

1. 线程同步之临界区

临界区不涉及到内核切换,只需要在用户态进行切换,所以效率比较高。
基本使用流程:
CRITICAL_SECTION cs;
InitializeCriticalSection(&cs); // 对应DeleteCriticalSection,只需调用一次。
EnterCriticalSection(&cs);
// ….
LeaveCriticalSection(&cs);
DeleteCriticalSection(&cs);

如果拥有临界区的线程意外终止,其他等待该临界区的线程会一直等待。

开发中经常对临界区进行如下封装:

class CritSec {
public:
    CritSec() {
        InitializeCriticalSection(&m_CS);
    }
    ~CritSec() {
        DeleteCriticalSection(&m_CS);
    }
    void Lock() {
        EnterCriticalSection(&m_CS);
    }
    void Unlock() {
        LeaveCriticalSection(&m_CS);
    }
    private:
        CritSec(const CritSec &refCritSec);
        CritSec &operator=(const CritSec &refCritSec);
        CRITICAL_SECTION m_CS;
}

还可以再次封装一层:

    class Locker {
    public:
        explicit Locker(CritSec *pCS) {
          m_pCS = pCS;
          m_pCS->Lock();
        }
        ~Locker() {
          m_pCS->Unlock();
        }
    private:
        Locker(const Locker &lock);
        Locker &operator=(const Locker &lock);
        CritSec* m_pCS;
    };

2. 线程同步之互斥体

HANDLE WINAPI CreateMutex(
  LPSECURITY_ATTRIBUTES lpMutexAttributes,
  BOOL bInitialOwner,
  LPCTSTR lpName
);

lpMutexAttributes:安全描述相关,如果需要跨线程共享该互斥体就需要设置该属性,否则只需要设置为NULL。
bInitialOwner:设置为TRUE表示创建线程持有该互斥体。如果为TRUE,则该线程创建完互斥体之后就持有该互斥体。
lpName:为互斥体指定名称,最大字符数为MAX_PATH。如果lpName为NULL,则创建没有名称的Mutex。

  • 如果指定的名称和现有的事件(Event)、信号量(Semaphore)、文件映射(file-mapping)、任务(job)、定时器(waitable-timer)等相同,则函数返回NULL,GetLastError返回ERROR_INVALID_HADNLE。
    如果指定的名称和现有的互斥体(Mutex)相同,且具有MUTEX_ALL_ACCESS权限,则返回该Handle,GetLastError返回ERROR_ALREADY_EXIST.
  • 名称以"Global\"开头,可以创建全局互斥体,在不同session间共享。
  • 函数成功返回句柄,失败返回NULL。句柄使用完之后需要使用CloseHandle关闭,防止句柄泄漏。
  • 互斥体在没有任何线程持有时,才是有信号状态。
  • 在拥有互斥体的线程意外终止后,系统后自动将互斥体内部持有线程ID重置为0,这样该互斥体又被置为了有信号状态。(被选中的线程的WaitForSingleObject()会返回WAIT_ABANDONED_0)

ReleaseMutex 释放线程对互斥体的拥有,互斥体处于有信号(signal)状态。

BOOL WINAPI ReleaseMutex(
  HANDLE hMutex
);

成功返回非0,失败返回0.

Paste_Image.png

3. 线程同步之事件

HANDLE CreateEvent(
  LPSECURITY_ATTRIBUTES lpEventAttributes,
  BOOL bManualReset,
  BOOL bInitialState,
  LPTSTR lpName
);

lpEventAttributes:安全描述符,一般设置为NULL。
bManualReset:事件信号是自动重置还是手动重置。自动重置在信号被释放之后(如WaitForSingleObject系列函数非超时返回),自动重置为非信号状态。
这个特性是互斥体和信号量所不具有的。
bInitialState:初始状态是否有信号。
lpName :事件名称,同互斥体。

4. 线程同步之信号量

HANDLE WINAPI CreateSemaphore(  
LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, 
LONG lInitialCount,  
LONG lMaximumCount,  
LPCTSTR lpName);

信号量在信号数大于0时才为有信号状态。
lInitialCount可以指定初始信号数,lInitialCount取值 [0, lMaximumCount]。

相关文章

  • windows线程同步

    1. 线程同步之临界区 临界区不涉及到内核切换,只需要在用户态进行切换,所以效率比较高。基本使用流程:CRITIC...

  • Windows 线程同步

    用户对象:简单高效,功能受限。 内核对象:复杂,但是功能多,可指定超时,防止死锁。 1.临界区(用户对象):适用范...

  • 新人小玩意儿-检测你的电脑配置是不是够好程序

    这个小玩意非常简单,采用windows接口完成 需要掌握的知识点: 进程、线程、同步、异步、windows API...

  • OpenMP多线程——Parallel for

    多线程——线程同步 数据竞争问题 线程互斥同步——critical 线程互斥同步——atmoic 线程互斥同步——...

  • windows线程同步对象mutex

    什么是mutex首先mutex是一个内核对象,不但可以用来做线程同步,还可以用来做进程间同步。 基本API2.1 ...

  • iOS线程同步

    iOS线程同步 iOS线程同步

  • 线程的基本语法

    线程同步[解决线程安全问题] 解决线程安全问题 线程同步方式一:同步代码 语法基本 synchronized (同...

  • iOS多线程小结

    同步异步串行并行 同步串行:不开启线程 同步并行:不开启线程 异步串行:最多开启一个线程 异步并行:开启线程 同步...

  • python防遗忘复习练手之:多线程

    多线程 线程同步

  • [C# 线程处理系列]专题四:线程同步

    目录: 一、线程同步概述 二、线程同步的使用 三 、总结 一、线程同步概述 前面的文章都是讲创建多线程来实现让我们...

网友评论

      本文标题:windows线程同步

      本文链接:https://www.haomeiwen.com/subject/qpqhtxtx.html