700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > LinuxC:锁 条件变量 信号量实现线程间的同步 生产者与消费者 pthread_mutex_init

LinuxC:锁 条件变量 信号量实现线程间的同步 生产者与消费者 pthread_mutex_init

时间:2020-12-01 14:54:56

相关推荐

LinuxC:锁 条件变量 信号量实现线程间的同步 生产者与消费者 pthread_mutex_init

死锁4个条件:1)互斥条件 2)不可剥夺条件 3)请求和保持条件 4)循环等待条件

管程:把锁和条件变量联合起来使用。锁实现互斥,条件变量实现同步。同步是协调多个线程运行速度

细度粒锁:减小一个锁所控制的共享数据量

递归锁:可以反复上锁,上锁多少次就要解锁多少次锁才能变为空闲。初始化pthread_mutex_t时将锁的类型设为PTHREAD_MUTEX_RECURSIVE即可设置递归锁

自旋锁

test_and_set(): 测试并设置指令。硬件提供 讲某一个位置的值的读取和设置值能成为不可分割的操作只适用于已知单个线程持有锁时间很短情况,缺点是效率低

struct lock {int value;}void lock_acquire(struct lock *my_lock) {//获得锁while (test_and_set(&my_lock->value));return ;}void lock_unlock(struct lock *my_lock) {//解锁my_lock->value = 0;return ;}

对换自旋锁. 硬件存储于内存中两个位置的值在一个不可分割的操作中对换

int test = 1;do {swap(&test, &lock);} while (test);

锁实现线程间的同步

mutex变量是非0即1,及可用资源数量创建锁 及 销毁锁

#include <pthread.h>//销毁pthread_mutex_init创建的mutexint pthread_mutex_destroy(pthread_mutex_t *mutex); //对mutex初始化,attr为mutex的属性//成功返回0,失败返回errnoint pthread_mutex_init(pthread_mutex_t *restrict mutex,const pthread_mutexattr_t * restrict attr);//mutex变量是全局变量或static变量,可用以下宏初始化//以下等价于pthread_mutex_init(mutex, NULL);pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

加锁及解锁. 成功返回0 失败返回errno

#include <pthread.h>//等待获得mutex锁int pthread_mutex_lock(pthread_mutex_t *mutex);//不等待获得mutex锁,若mutex被其他线程用则推出等待立即返回EBUSYint pthread_mutex_trylock(pthread_mutex_t *mutex);int pthread_mutex_unlock(pthread_mutex_t *mutex);

死锁

1)一个线程先后两次调用lock(),导致永远等待被自己占用的锁,陷入死锁

2)两个线程分别获得了锁后,分别调用对方的锁,导致双方永远挂起状态陷入死锁

条件变量实现线程间的同步

条件变量阻塞等待一个条件,或唤醒等待这个条件的线程创建条件变量 及 销毁条件变量. 成功返回0,失败返回errno

#include <pthread.h>int pthread_cond_destroy(pthread_cond_t *cond);int pthread_cond_init(pthread_cond_t *restrict cond,const pthread_condattr_t *restrict attr);//以下等价于pthread_cond_init(cond, NULL);pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

条件变量操作函数。成功返回0,失败返回errno

#include <pthread.h>//abstime指定的时刻仍没有线程唤醒当前进程,返回ETIMEOUTint pthread_cond_timedwait(pthread_cond_t *restrict cond,pthread_mutex_t *restrict mutex,const struct timespec *restrict abstime);//阻塞等待条件变量发生int pthread_cond_wait(pthread_cond_t *restrict cond,pthread_mutex_t *restrict mutex);//唤醒条件变量下等待的所有线程int pthread_cond_broadcast(pthread_cond_t *cond);//唤醒条件变量下等待的线程int pthread_cond_signal(pthread_cond_t *cond);

条件变量实现生产者与消费者

#include <stdio.h>#include <stdlib.h>#include <time.h>#include <unistd.h>#include <pthread.h>pthread_mutex_t headlock = PTHREAD_MUTEX_INITIALIZER;pthread_cond_t hadGoods = PTHREAD_COND_INITIALIZER;typedef struct Goods {int data;struct Goods *next;} Goods;Goods *head = NULL;void *producer(void *arg) {//生成者Goods *ng;while (1) {ng = (Goods *)malloc(sizeof(Goods));ng->data = rand() % 100;pthread_mutex_lock(&headlock);//头插法ng->next = head;head = ng;pthread_mutex_unlock(&headlock);pthread_cond_signal(&hadGoods);printf("producer %d\n", ng->data);sleep(rand() % 3);}}void *consumer(void *arg) {//消费者Goods *k;while (1) {pthread_mutex_lock(&headlock);if (!head) {pthread_cond_wait(&hadGoods, &headlock);}k = head;head = head->next;pthread_mutex_unlock(&headlock);printf("consumer %d\n", k->data);free(k);sleep(rand() % 3);}}int main() {srand(time(NULL));pthread_t pid, cid;pthread_create(&pid, NULL, producer, NULL);pthread_create(&cid, NULL, consumer, NULL);pthread_join(pid, NULL);pthread_join(cid, NULL);return 0;}

信号量实现线程间的同步

信号量可用于同一进程间的同步,也可用于不同进程间的同步

semaphore可用资源数有多个,和mutex不同点在于可以大于1

#include <semaphore.h>//初始化sem_t变量,value-可用资源数//pshared=0表示信号量用于同一进程的线程间同步int sem_init(sem_t *sem, int pshared, unsigned int value);//获得资源,sem_t值减1,如果减1前值为0则挂起等待int sem_wait(sem_t *sem); //获得资源,sem_t值减1,如果减1前值为0则不会挂起等待int sem_trywait(sem_t *sem); //sem_t值加1,且唤醒挂起等待的线程int sem_post(sem_t *sem); int sem_destroy(sem_t *sem); //释放信号量资源

信号量实现生产者与消费者

#include <stdio.h>#include <stdlib.h>#include <time.h>#include <unistd.h>#include <pthread.h>#include <semaphore.h>int q[5];sem_t nil_no, goods_no;void *producer(void *arg) {int i = 0;while (1) {sem_wait(&nil_no);q[i] = rand() % 100 + 1;printf("producer %d\n", q[i]);sem_post(&goods_no);i = (i + 1) % 5;sleep(rand() % 3);}}void *consumer(void *arg) {int i = 0;while (1) {sem_wait(&goods_no);printf("consumer %d\n", q[i]);q[i] = 0;sem_post(&nil_no);i = (i + 1) % 5;sleep(rand() % 3);}}int main() {srand(time(NULL));sem_init(&nil_no, 0, 5);sem_init(&goods_no, 0, 0);//macOS//sem_open("nil_no", O_CREAT|O_EXCL, S_IRWXU, 5);//sem_open("goods_no", O_CREAT|O_EXCL, S_IRWXU, 0);pthread_t pid, cid;pthread_create(&pid, NULL, producer, NULL);pthread_create(&cid, NULL, consumer, NULL);pthread_join(pid, NULL);pthread_join(cid, NULL);return 0;}

LinuxC:锁 条件变量 信号量实现线程间的同步 生产者与消费者 pthread_mutex_init pthread_cond_init sem_init

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。