#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;
}

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

被折叠的 条评论
为什么被折叠?



