多线程编程中为了保证共享对象的同步,经常组合使用mutex&condition,优点就是简单易用。
多线程编程中往往需要组合使用thread、mutex、condition,而这三个类都包含在pthread.h中,他们的函数名也统一以pthread_开头。
thread常用接口:
pthread_create(父线程调用,创建子线程)
pthread_exit(退出线程,不过当前线程资源不会立即释放,直到进程退出才行)
pthread_join(父线程调用,父线程在当前位置等待子线程退出,子线程退出时释放资源)
pthread_detach(分离父子线程,子线程退出后自行释放资源)
注意:创建线程也可能导致内存泄漏,解决方法:1>在父线程调用pthread_join等待子线程退出,特点是会造成父线程堵塞;2>父线程或子线程调用pthread_detach,子线程退出后自行释放资源,特点是不会造成父线程堵塞。
mutex常用接口:
pthread_mutex_init(初始化mutex)
pthread_mutex_destroy(销毁mutex)
pthread_mutex_lock(上锁)
pthread_mutex_unlock(解锁)
condition常用接口:
pthread_cond_init(初始化condition)
pthread_cond_destroy(销毁condition)
pthread_cond_wait(持续等待直到被唤醒)
pthread_cond_timedwait(等待指定时间未被唤醒也返回)
pthread_cond_signal(唤醒等待中的某一个condition)
pthread_cond_broadcast(唤醒所有等待中的condition)
下面写一个简易demo看看thread、mutex、condition之间的协同工作
#include<vector>
#include<pthread.h>
std::vector<int> g_vec;
pthread_mutex_t g_mutex;
pthread_cond_t g_cond;
void* threadFun(void*)
{
std::cout<<"threadFun"<<std::endl;
//读操作加锁
pthread_mutex_lock(&g_mutex);
//这里最好用while不用if,防止当前条件变量被虚假唤醒
while (g_vec.empty())
{
//等待条件变量时会解锁,此时父线程可以对g_vec进行写操作
pthread_cond_wait(&g_cond, &g_mutex);
//条件变量被唤醒后会上锁
}
std::cout<<"size:"<<g_vec.size()<<std::endl;
//do something...
pthread_mutex_unlock(&g_mutex);
}
int main()
{
//初始化互斥锁
pthread_mutex_init(&g_mutex, NULL);
//初始化条件变量
pthread_cond_init(&g_cond, NULL);
pthread_t t_id;
if(pthread_create(&t_id, NULL, threadFun, NULL))
{
std::cout<<"pthread_create error"<<std::endl;
exit(0);
}
sleep(3);
//写操作加锁
pthread_mutex_lock(&g_mutex);
g_vec.push_back(999);
//先解锁再唤醒
pthread_mutex_unlock(&g_mutex);
//唤醒另一个处于等待状态的条件变量g_cond,若想唤醒所有则用broadcast方式
pthread_cond_signal(&g_cond);
//等待子线程退出
pthread_join(t_id, NULL);
return 0;
}