互斥锁同步互斥
为了保护共享资源,使我们线程可以单独使用某个共享资源,使用之前先上锁,当其他进程要使用的时候,就需要等待到这个线程用完之后,再开锁。
- 声明互斥锁:
pthread_mutex_t m
;
- 初始化互斥锁:
int pthread_mutex_init(pthread_mutex_t *restrict mutex,const pthread_mutexattr_t *restrict attr);
第一个参数:就是前面声明的锁,因为这个参数需要传递的是一个锁的指针,所以需要有一个取地址符。第二个参数:是这个锁的属性,我们让它是默认的属性,这里设置为NULL,返回值:成功返回0, 失败返回-1。
- 上锁:锁住某个资源
int pthread_mutex_lock(pthread_mutex_t *mutex);
这个函数是阻塞型。int pthread_mutex_trylock(pthread_mutex_t *mutex);
这个是非阻塞型的。返回值:成功返回0,失败返回-1.
- 解锁:
int pthread_mutex_unlock(pthread_mutex_t *mutex);
返回值:成功返回0,失败返回-1.
- 销毁互斥锁:
int pthread_mutex_destroy(pthread_mutex_t *mutex);
返回值:成功返回0, 失败返回-1。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
| #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <pthread.h> #include <string.h>
pthread_mutex_t mutex; char* buf[5]; int pos;
void* task(void* p) { pthread_mutex_lock(&mutex);
buf[pos] = (char*)p; sleep(1); pos++;
pthread_mutex_unlock(&mutex); }
void* task2(void* p) { pthread_mutex_lock(&mutex);
buf[pos] = (char*)p; sleep(1); pos++;
pthread_mutex_unlock(&mutex); }
int main(void) { pthread_mutex_init(&mutex, NULL);
pthread_t tid, tid2; pthread_create(&tid, NULL, task, (void*)"贾鹏城\n"); pthread_create(&tid2, NULL, task2, (void*)"OperatingSystem\n");
pthread_join(tid, NULL); pthread_join(tid2, NULL);
pthread_mutex_destroy(&mutex);
int i = 0; printf("字符指针数组中的内容是:\n"); for (i = 0; i < pos; ++i) { printf("%s ", buf[i]); }
}
|
读写锁同步互斥
读写锁:
如果某线程申请了读锁,其它线程可以再申请读锁,但不能申请写锁;如果某线程申请了写锁,其它线程不能申请读锁,也不能申请写锁。
读写锁适合于对资源的读次数比写次数多得多的情况。
实例,两个读线程两个写线程,写互斥地对字符数组操作。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
| #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <pthread.h> #include <string.h> char cBuf[30]; pthread_rwlock_t rwlock;
void *taskWrite(void *p) { while (1) { pthread_rwlock_wrlock(&rwlock); if (pos < 29) { cBuf[pos] = 'A'; pos++; printf("Write cBuf is: %s \n", cBuf); } pthread_rwlock_unlock(&rwlock); sleep(1); } }
void *taskWriteDel(void *p) { while (1) { pthread_rwlock_wrlock(&rwlock); if (pos > 0) { cBuf[pos-1] = 0; pos--; printf("WriteDel cBuf is: %s \n", cBuf); } pthread_rwlock_unlock(&rwlock); sleep(1); } } void *taskRead(void *p) { while (1) { pthread_rwlock_rdlock(&rwlock); if (pos > 0) { printf("read cBuf is: %s \n", cBuf); } pthread_rwlock_unlock(&rwlock); } } void *taskRead2(void *p) { while (1) { pthread_rwlock_rdlock(&rwlock); if (pos > 0) { printf("read2 cBuf is: %s \n", cBuf); } pthread_rwlock_unlock(&rwlock); } } int main(void) { pthread_t ptd1, ptd2, ptd3, ptd4; pos = 0; pthread_rwlock_init(&rwlock, NULL); pthread_create(&ptd1, NULL, taskWrite, NULL); pthread_create(&ptd2, NULL, taskWriteDel, NULL); pthread_create(&ptd3, NULL, taskRead, NULL); pthread_create(&ptd4, NULL, taskRead2, NULL); pthread_join(ptd1, NULL); pthread_join(ptd2, NULL); pthread_join(ptd3, NULL); pthread_join(ptd4, NULL); pthread_rwlock_destroy(&rwlock); }
|
自旋锁
自旋锁与互斥量功能一样,唯一一点不同的就是互斥量阻塞后休眠让出cpu,而自旋锁阻塞后不会让出cpu,会一直忙等待,直到得到锁。
接口上就是把互斥锁的mutex改成spin。
实例 两个线程各自数数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
| #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <pthread.h> #include <string.h> pthread_spinlock_t spinMutex; void *task5(void *p) { int cur = 0; while (1) { pthread_spin_lock(&spinMutex); printf("task5 %d\n", cur); cur++; sleep(0); pthread_spin_unlock(&spinMutex); } } void *task6(void *p) { int cur = 0; while (1) { pthread_spin_lock(&spinMutex); printf("task6 %d\n", cur); cur++; sleep(0); pthread_spin_unlock(&spinMutex); } } int main(void) { pthread_spin_init(&spinMutex, NULL); pthread_t tid3, tid4; pthread_create(&tid3, NULL, task5, (void *)"zhangfei"); pthread_create(&tid4, NULL, task6, (void *)"zhangfei"); pthread_join(tid3, NULL); pthread_join(tid4, NULL); pthread_spin_destroy(&spinMutex); }
|