互斥锁
使用mutex(互斥量)一般步骤
1.pthread_mutex_t mutex;创建锁
2.pthread_mutex_init:初始化
3.pthread_mutex_lock:加锁
4访问共享数据(stdout)
5.pthread_mutex_unlock:解锁
6.pthread_mutex_destroy:销毁锁
#include #include #include #include #include //pthread_mutex_t 互斥锁类型名,线程属性pthread_mutex_t mutex;//定义另一个互斥锁变量mutex,线程属性全局变量,线程属性所有线程可以共享使用void *tfn2(void *arg){ //当某个线程,线程属性不进行对共享资源进行加锁操作时,线程属性仍旧会造成抢夺资源现象 srand(time(NULL)); while(1) { int ret=pthread_mutex_trylock(&mutex); if(ret!=0) { printf("pthread_mutx_trylock err:%s\n",线程属性strerror(ret)); } else { printf("---tfn2()---print "); sleep(rand() % 3); printf("to stdout\n"); sleep(rand() % 3); ret=pthread_mutex_unlock(&mutex);//解锁 if(ret!=0) { fprintf(stderr,"pthread_mutex_unlock() error:%s\n",strerror(ret)); } } printf("common tfn2()------\n"); sleep(rand() % 3); }}void *tfn(void *arg){ srand(time(NULL)); while (1) { int ret=pthread_mutex_lock(&mutex);//加锁 if(ret!=0) { fprintf(stderr,"pthread_mutex_lock() error:%s\n",strerror(ret)); } printf("hello "); sleep(rand() % 3); printf("world\n"); //pthread_mutex_unlock(),对加锁成功的共享资源进行解锁 ret=pthread_mutex_unlock(&mutex);//解锁 if(ret!=0) { fprintf(stderr,"pthread_mutex_unlock() error:%s\n",strerror(ret)); } sleep(rand() % 3); } return NULL;}int main(void){ pthread_t tid; srand(time(NULL)); //pthread_mutex_init()初始化 互斥锁 int ret=pthread_mutex_init(&mutex,NULL);//初始化锁 if(ret!=0) { fprintf(stderr,"mutex init error:%s\n",strerror(ret)); } //pthread_create() 创建线程1 ret=pthread_create(&tid, NULL, tfn, NULL); if(ret!=0) { fprintf(stderr,"pthread_create error:%s\n",strerror(ret)); } //pthread_create() 创建线程2 ret=pthread_create(&tid, NULL, tfn2, NULL); if(ret!=0) { fprintf(stderr,"pthread_create error:%s\n",strerror(ret)); } while (1) { //pthread_mutex_lock()给已初始化过的互斥锁变量,(站在当前线程角度)对共享资源进行加锁操作 //如果加锁失败,线程属性则阻塞,线程属性也就是线程属性一直等待 ret=pthread_mutex_lock(&mutex);//加锁 if(ret!=0) { fprintf(stderr,"pthread_mutex_lock() error:%s\n",strerror(ret)); } printf("HELLO "); sleep(rand() % 3); printf("WORLD\n"); //pthread_mutex_unlock(),对加锁成功的共享资源进行解锁 ret=pthread_mutex_unlock(&mutex);//解锁 if(ret!=0) { fprintf(stderr,"pthread_mutex_unlock() error:%s\n",strerror(ret)); } sleep(rand() % 3); } pthread_join(tid, NULL); ret=pthread_mutex_destroy(&mutex);//销毁锁 if(ret!=0) { fprintf(stderr,"pthread_mutex_destroy() error:%s\n",strerror(ret)); } return 0;}
读写锁
特别强调,读写锁只有一把,线程属性但具备两种状态:
1读模式下加锁状态(读锁)
2.写模式下加锁状态(写锁)
特征:
1.读写锁是线程属性“写模式加锁”成功时,其它线程加锁都会被阻塞
2.读写锁“读模式加锁”成功时,线程属性其他线程以写模式加锁会阻塞
3.读锁、线程属性写锁并行阻塞,线程属性写锁优先级高。线程属性读锁也叫共享
#include #include #include int counter=0;//用pthread_rwlock_t类型,定义读写锁变量rwlockpthread_rwlock_t rwlock;/* 3个线程不定时写同一全局资源,5个线程不定时读同一全局资源*/void *th_write(void *arg){ int t; int i = (long int)arg; while (1) { pthread_rwlock_wrlock(&rwlock);//以写模式加锁 t = counter; counter++;// sleep(1); printf("=====write i=%d:tid=%lu:counter=%d ++counter=%d\n", i, pthread_self(), t, counter); pthread_rwlock_unlock(&rwlock); sleep(1); } return NULL;}void *th_read(void *arg){ int i = (long int)arg; while (1) { pthread_rwlock_rdlock(&rwlock);//读线程间,读锁共享 printf("----------------------read i=%d:tid=%lu:counter=%d\n", i, pthread_self(), counter); pthread_rwlock_unlock(&rwlock); usleep(100000); } return NULL;}int main(void){ long int i; pthread_t tid[8]; pthread_rwlock_init(&rwlock, NULL); for(i=0;i<3;i++) { pthread_create(&tid[i], NULL, th_write, (void *)i); } for(i=0;i<5;i++) { pthread_create(&tid[i+3], NULL, th_read, (void *)i); } for(i=0;i<8;i++) { pthread_join(tid[i], NULL); } pthread_rwlock_destroy(&rwlock); return 0;}