天天看点

使用互斥锁和条件变量实现windows的Event

#include<iostream>
#include<unistd.h>
#include<pthread.h>
using namespace std;

class DEvent
{
	public:
		DEvent(bool bSet):bSet(bSet)
		{
			pthread_mutex_init(&mutex, NULL);	
			pthread_cond_init(&cond, NULL);
		}

		~DEvent()
		{
			pthread_mutex_destroy(&mutex);	
			pthread_cond_destroy(&cond);
		}

		void Wait()
		{
			pthread_mutex_lock(&mutex);
			while (!bSet)
			{
				pthread_cond_wait(&cond, &mutex);
			}
			bSet = false;//自动置位
			pthread_mutex_unlock(&mutex);
		}

		void SetEvent()
		{
			pthread_mutex_lock(&mutex);
			bSet = true;
			pthread_cond_signal(&cond);
			pthread_mutex_unlock(&mutex);
		}

	public:
		bool bSet = false;
		pthread_mutex_t mutex;
		pthread_cond_t cond;
};

DEvent eventA(true);
DEvent eventB(false);

void* PrintA(void* arg)
{
    while (true)
	{
	eventA.Wait();
	cout << "A" << endl;
	sleep(1);
	eventB.SetEvent();
	}
	return 0;
}

void* PrintB(void* arg)
{
	while (true)
	{
	eventB.Wait();
	cout << "B" << endl;
	eventA.SetEvent();
	}
	return 0;
}

//使用DEvent使得两个线程交替输出AB
int main(int argc, char** argv)
{
	pthread_t tid1, tid2;
	pthread_create(&tid1, NULL, PrintA, NULL);
	pthread_create(&tid2, NULL, PrintB, NULL);

	pthread_join(tid2, NULL);
	pthread_join(tid1, NULL);
	return 0;
}
           

(1)互斥锁

pthread_mutex_t mutex;

互斥锁用到的4个函数

初始化互斥锁:

pthread_mutex_init(pthread_mutex_t *mutex, pthread_mutexattr_t *attr);

加锁:

pthread_mutex_lock(pthread_mutex_t *mutex);

解锁:

pthread_mutex_unlock(pthread_mutex_t *mutex);

销毁互斥锁:

pthread_mutex_destroy(pthread_mutex_t *mutex);

关于初始化:

如果是静态初始化,则不用调用pthead_mutex_init和pthread_mutex_destroy这两个函数,静态初始化如下:

pthread_mutex_t cond = PTHREAD_MUTEX_INITIALIZER;

当互斥锁存放在共享内存中或者动态申请(malloc)的空间中时,必须使用pthread_mutex_init来初始化。

关于pthread_mutex_init函数的第二个参数,互斥锁的属性,一般可以是NULL,但是当互斥锁在共享内存中并且需要在多进程使用时,必须给互斥锁初始化PTHREAD_PROCESS_SHARED属性,才能正确在多进程间共享,代码如下:

pthread_mutexattr_t attr; //这个属性结构可以是在本地的临时变量,执行完pthread_mutex_init函数之后就可以销毁

pthread_mutexattr_init(&attr);//初始化属性

pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);

pthread_mutex_init(pMutex, &attr);//pthread_mutex_t结构体必须在共享内存中

pthread_mutexattr_destroy(&attr);//初始化执行完就可以销毁了
           

条件变量在多进程间共享也是一样的道理,把以上代码的mutex改成cond就可以了

(2)条件变量

pthead_cond_t cond;

条件变量用到的4个函数

初始化信号量:

pthead_cond_init(pthread_cond_t *cond, pthread_condattr_t *attr);

等待信号量:(等待信号量函数必须关联一个互斥锁,信号量的操作必须是在锁住某个资源然后查看资源的状态后才觉得是否要等待)

pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);

唤醒等待的线程:

pthread_cond_signal(pthread_cond_t *cond);

销毁条件变量:

pthread_cond_destroy(pthread_cond_t *cond);

如果是静态初始化,则不用调用pthead_cond_init和pthread_cond_destroy这两个函数,静态初始化如下:

pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

继续阅读