C++条件变量实现

这个博客展示了在Windows和Unix环境下实现条件变量的类`CondVito`,用于多线程同步。类中包含了信号、广播、等待等操作,并在析构时正确释放资源。在`main`函数中通过`CondVito`实现了两个线程间的同步,一个线程负责递减计数,另一个负责递增计数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#ifndef COND_VITO_H
#define COND_VITO_H

#ifdef _WIN32
#include<windows.h>
#else
#include <pthread.h>
#endif

class CondVito
{
public:
    CondVito();
    ~CondVito();
    void signal();
    void broadcast();
    void waitImpl() const;
    //bool timedWaitImpl() const;


private:
#ifdef _WIN32
    mutable CRITICAL_SECTION _mutex;
    mutable CONDITION_VARIABLE _cond;
#else
    mutable pthread_mutex_t _mutex;
    mutable pthread_cond_t _cond;
#endif

};

#endif

#include "CondVito.h"
#include<assert.h>

 

CondVito::CondVito()
{
#ifdef _WIN32
    InitializeCriticalSection(&_mutex);
    InitializeConditionVariable(&_cond);
#else
    int rc;
    pthread_mutexattr_t attr;
    rc = pthread_mutexattr_init(&attr);
    assert(rc == 0);
    if (rc != 0)
    {
        pthread_mutexattr_destroy(&attr);
    }
#ifndef NDEBUG
#if defined(__linux) && !defined(__USE_UNIX98)
    rc = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK_NP);
#else
    rc = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
#endif
    assert(rc == 0);
    if (rc != 0)
    {
        pthread_mutexattr_destroy(&attr);

    }
#endif
#if defined(_POSIX_THREAD_PRIO_INHERIT) && _POSIX_THREAD_PRIO_INHERIT > 0
    if (PrioInherit == protocol)
    {
        rc = pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_INHERIT);
        if (rc != 0)
        {
            pthread_mutexattr_destroy(&attr);
        }
}
#endif
    rc = pthread_mutex_init(&_mutex, &attr);
    assert(rc == 0);
    if (rc != 0)
    {
        pthread_mutexattr_destroy(&attr);
    }
    rc = pthread_mutexattr_destroy(&attr);
    assert(rc == 0);
    pthread_condattr_t attr2;
    rc = pthread_condattr_init(&attr2);
    if (rc != 0)
    {
        
    }

#if !defined(__hppa) && !defined(__APPLE__) && !defined(__FreeBSD__)
    rc = pthread_condattr_setclock(&attr2, CLOCK_MONOTONIC);
    if (rc != 0)
    {
        
    }
#endif

    rc = pthread_cond_init(&_cond, &attr2);
    if (rc != 0)
    {
        
    }
    rc = pthread_condattr_destroy(&attr2);
    if (rc != 0)
    {
        
    }
#endif
}


CondVito::~CondVito()
{
#ifndef _WIN32
#ifndef NDEBUG
    int rc = pthread_cond_destroy(&_cond);
    assert(rc == 0);
#else
    pthread_cond_destroy(&_cond);
#endif
#endif
}


void CondVito::signal()
{
#ifdef _WIN32
    WakeConditionVariable(&_cond);
#else
    int rc = pthread_cond_signal(&_cond);
    if (rc != 0)
    {
        
    }
#endif
}
void CondVito::broadcast()
{
#ifdef _WIN32
    WakeAllConditionVariable(&_cond);
#else
    int rc = pthread_cond_broadcast(&_cond);
    if (rc != 0)
    {
        
    }
#endif
}
void CondVito::waitImpl() const
{
#ifdef _WIN32
    EnterCriticalSection(&_mutex);
    BOOL ok = SleepConditionVariableCS(&_cond, &_mutex, INFINITE);
    LeaveCriticalSection(&_mutex);
#else
    int rc = pthread_mutex_lock(&_mutex);
    rc = pthread_cond_wait(&_cond, &_mutex);
    rc = pthread_mutex_unlock(&_mutex);
#endif
}

 

#include "MutexVito.h"
#include "ThreadVito.h"
#include "CondVito.h"
#include<iostream>
#include<thread>

#ifdef _WIN32
#include<windows.h>
#include<process.h>
#else
#include <pthread.h>
#include <unistd.h>
#endif


int count = 0;
CondVito cond;
void de()
{
    while (true)
    {
        printf("in derement.\n");
        if (count == 0)
        {
            cond.waitImpl();
        }
        count--;
        printf("----decrement:%d.\n", count);
        printf("out decrement.\n");
        sleep(1);
    }
}

void in() {
    while (true)
    {
        printf("in increment.\n");
        count++;
        printf("----increment:%d.\n", count);
        if (count != 0)
            cond.signal();
        printf("out increment.\n");
        sleep(2);
    }
}


void test_cond()
{
    std::thread t1(de);
    std::thread t2(in);

    t1.join();
    t2.join();
}

int main()
{
    test_cond();
    return 0;
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值