线程的修炼3

来源:互联网 发布:电脑屏幕颜色校准软件 编辑:程序博客网 时间:2024/04/30 08:19
线程锁:因为多个线程共享相同的内存,所以需要确保每个线程看到一致的数据。如果数据是只读的,那么不存在一致性问题。但是如果线程对数据有读有写,此时需要同步机制来保证数据的一致性。需要一种机制确保变量修改时,只有一个线程在访问。这样就能保证数据的一致性。这时候就需要线程锁了。1.互斥量:用pthread_mutex_t mutex来定义一把锁.mutex是锁名。int pthread_mutex_init ( pthread_mutex_t *mutex, const pthread_mutexattr_t * attr );mutex为锁名的取地址,attr为属性,可以写NULL。关于上锁,解锁的3个函数:int pthread_mutex_lock(pthread_mutex_t *mutex);int pthread_mutex_trylock(pthread_mutex_t *mutex); int pthread_mutex_unlock(pthread_mutex_t*mutex);pthread_mutex_lock给互斥量mutex加锁。如果此互斥量已经加锁,那么调用该函数的线程会被阻塞;如果互斥量没加锁,调用线程给该互斥量加锁。Pthread_mutex_trylock尝试给互斥量mutex加锁,看锁是否能加上。 如果所能加上则返回0,不能加上则errno设置成EBUSY,错误返回其余值。pthread_mutex_unlock给互斥量解锁。成功返回0,失败返回非0.下面是一个用互斥量写的死锁:
#include <stdio.h>#include <pthread.h>pthread_mutex_t mutex1;pthread_mutex_t mutex2;void *thread1(void *arg){printf("thread1 trying to lock mutex1...\n");pthread_mutex_lock(&mutex1);printf("thread1 lock succeed mutex1...\n");sleep(5);printf("thread1 trying to lock mutex2...\n");pthread_mutex_lock(&mutex2);printf("thread1 try to unlock mutex1");pthread_mutex_unlock(&mutex1);printf("thread1 success to unlock mutex1...\n");}void *thread2(void* arg){printf("thread2 try to lock mutex2...\n");pthread_mutex_lock(&mutex2);printf("thread2 lock succeed mutex2...\n");sleep(5);printf("thread2 try to lock mutex1...\n");pthread_mutex_lock(&mutex1);printf("thread2 try to unlock mutex2");pthread_mutex_unlock(&mutex2);printf("thread2 success to unlock mutex2...\n");}int main(){int i;int num;pthread_t tid;pthread_attr_t attr;pthread_attr_init(&attr);pthread_mutex_init(&mutex1,NULL);pthread_mutex_init(&mutex2,NULL);pthread_create(&tid,&attr,thread1,NULL);pthread_create(&tid,&attr,thread2,NULL);getchar();}
2.读写锁:
读写锁有三个状态:读锁、写锁、不加锁。同一时刻只有一个线程能拥有写锁,但是同一时刻可以有多个线程可以拥有读锁。
加了写锁后,任何线程都不能再加锁,无论读写。
加了读锁后,任何线程都可以对它加读锁,但不能加写锁。
读写锁适合读比较频繁,写比较少的情况,比如数据库。
用pthread_rwlock_t rwlock来定义一把锁.rwlock是锁名。
int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock,  const  pthread_rwlockattr_t   *restrict attr)
rwlock为锁名的取地址,attr为属性,可以写NULL。
当要释放读写锁时,必须先调用destroy函数:
int pthread_rwlock_destroy(pthread_rwlock_t *rwlock); 
加解读写锁函数:
int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock); 
int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock); 
int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);
int pthread_rwlock_tryrdlock(pthread_rwlock_t   *rwlock); 
int pthread_rwlock_trywrlock(pthread_rwlock_t   *rwlock);
加读锁时要注意判断返回值,因为加读锁的次数可能有限制!所以加读锁是会失败的。
加写锁无须判断返回值,写锁只能加一次。
无论加的是写锁还是读锁,都用pthread_rwlock_unlock解锁。
成功返回0,不成功返回非0

tryrdlock和trywrlock检查是否能加锁,能加锁返回0,不能加锁返回EBUSY,失败返回其余值。

#include#includepthread_rwlock_t rwlock; void *fun1(void *arg) {  printf("thread1 try to lock rdlock\n"); pthread_rwlock_rdlock(&rwlock); printf("thread1 success to lock rdlock\n"); sleep(1); pthread_rwlock_unlock(&rwlock); printf("thread1 success to unlock\n"); sleep(1); printf("thread1 try to lock rdlock\n");pthread_rwlock_rdlock(&rwlock); printf("thread1 success to lock rdlock\n");  } void *fun2(void *arg) { printf("thread2 try to lock rdlock\n"); pthread_rwlock_rdlock(&rwlock); printf("thread2 success to lock rdlock\n"); sleep(1); pthread_rwlock_unlock(&rwlock); printf("thread2 success to unlock\n"); sleep(1); printf("thread2 try to lock rdlock\n"); pthread_rwlock_rdlock(&rwlock); printf("thread2 success to lock rdlock\n"); }void *fun3(void *arg){printf("thread3 try to lock wrlock\n"); pthread_rwlock_wrlock(&rwlock); printf("thread3 success to lock wrlock\n"); sleep(1); pthread_rwlock_unlock(&rwlock); printf("thread3 success to unlock\n"); }int main () { pthread_rwlock_init(&rwlock,NULL); pthread_t tid; pthread_create(&tid,NULL,fun1,NULL); pthread_create(&tid,NULL,fun2,NULL); pthread_create(&tid,NULL,fun3,NULL); getchar(); return 0;  }
条件锁:haimeixie 


0 0
原创粉丝点击