一、前言
本篇主要讨论线程同步、互斥量等概念
二、涉及的pthread变量
pthread_t: 线程标识符
pthread_mutex_t: 互斥量
pthread_code_t: 条件变量
pthread_key_t: 线程私有权握访问键
pthread_attr_t 线程属性对象
pthread_mutex_attr_t: 互斥量属性对象
pthread_cond_attr_t: 条件变量属性对象
三、互斥量
为了避免多线程在同一时刻访问(同时读或写)某一变量,可以使用互斥量加锁(实际是加锁了一段代码)形式使某一时刻只能有一个线程访问某个资源,以下为例子,只有当主线程(或子线程)解锁了之后,另一方面才能开始再加锁。
#include <iostream>
#include <stdio.h>
#include <cstdlib>
#include <pthread.h>
#include <unistd.h>
using namespace std;
int run_now=1; //run_now 代表共享资源
pthread_mutex_t work_mutex; //定义互斥量
void *thread_function( void *arg)
{
int print_count2 = 0 ;
if( pthread_mutex_lock( &work_mutex ) != 0){
cout<<"func thread lock failed\n";
}else{
cout<<"func thread lock sucess\n";
}
while(print_count2++<5 ){
if(run_now == 2 ){
printf("function thread is run\n");
run_now = 1;
}else{
printf("function thread is sleep\n");
sleep(1);
}
}
if( pthread_mutex_unlock( &work_mutex ) != 0){
cout<<"func thread unlock failed\n";
}else{
cout<<"func thread unlock sucess\n";
}
pthread_exit( (void*)"func exit!\n" );
}
int main()
{
int print_count1 = 0 ;
pthread_t id;
//初始化静态互斥量
if( pthread_mutex_init( &work_mutex , NULL ) != 0 ){
cout<<"Mutex init failed\n";
return -1;
}
int ret = pthread_create( &id , NULL , thread_function , NULL );
if( ret == -1){
cout<<"thread create error!\n";
return -1;
}
//给互斥量加锁
if( pthread_mutex_lock( &work_mutex ) != 0){
cout<<"mian thread lock failed\n";
return -1;
}else{
cout<<"mian thread lock sucess\n";
}
while( print_count1++<5){
if(run_now == 1){
printf("main thread is run\n");
run_now = 2;
}else{
printf("main thread is sleep\n");
sleep(1);
}
}
//给互斥量解锁
if( pthread_mutex_unlock( &work_mutex ) != 0){
cout<<"mian thread unlock failed\n";
return -1;
}else{
cout<<"mian thread unlock sucess\n";
}
void * message;
pthread_join( id , &message);
printf("recived message:%s" , (char*)message );
return 0;
}
运行结果如下:
四、条件变量
条件变量可以被用来实现这两进程间的线程同步,通常条件变量和互斥锁同时使用。条件变量的使用可被表述为:线程A在某种条件下进入等待状态, 这时它将自动阻塞,释放等待状态改变的互斥锁;直到线程B改变这种条件,并发信号给关联的条件变量,唤醒线程A(也可以是多个),重新获得互斥锁。
#include <iostream>
#include <stdio.h>
#include <cstdlib>
#include <pthread.h>
#include <unistd.h>
using namespace std;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; // 初始化互斥量
pthread_cond_t cond = PTHREAD_COND_INITIALIZER; //初始化条件变量,通常为全局
void *thread1(void *);
void *thread2(void *) ;
int i = 1;
int main()
{
pthread_t p_a;
pthread_t p_b;
pthread_create( &p_b , NULL , thread1 , NULL );
pthread_create( &p_a , NULL , thread2 , NULL );
pthread_join( p_b , NULL ) ; //p_a则不用等待了
pthread_mutex_destroy( &mutex );
pthread_cond_destroy( &cond );
exit(0);
return 0;
}
void *thread1(void *) //p_a执行的
{
for( i = 1 ; i < 20 ; ++i){
pthread_mutex_lock(&mutex );
if( i %3 == 0) // i 为3的整数倍则发信号
pthread_cond_signal( &cond );
else
std::cout<<"thread1:"<<i<<std::endl;
pthread_mutex_unlock(&mutex );
sleep(1);
}
}
void *thread2(void *) //p_b执行的
{
while(i <13){ // i 为12时进入等待,故i为15时也将被打印
pthread_mutex_lock(&mutex );
if( i %3 != 0){ // i 不为3的整数倍则等待
pthread_cond_wait( &cond, &mutex );
}
std::cout<<"thread2:"<<i<<std::endl;
pthread_mutex_unlock(&mutex );
sleep(1);
}
}
运行结果