0


linux_信号量(详解)

一.信号量

1.1信号量的概述

信号量广泛用于进程或线程间的同步和互斥,信号量本质上是一个非负整数计数器,它被用来控制对公共资源的访问

编程时可根据操作信号量值的结果判断是否对公共资源具有访问的权限,当信号量大于0时,则可以访问,否则将阻塞

信号量又称之为PV操作,P V原语是对信号量的操作,一次P操作使信号量使信号量sem-1一次V操作使信号量sem+1,对于P操作,如果信号量的sem值小于等于0,则P操作就会阻塞,如果信号量的值大于0,才可以执行p操作进行减1

信号量主要用于进程或线程间的同步和互斥这两种情况

  1. 若用于互斥,几个进程(或线程)往往只设置一个信号量
  2. 若用于同步操作,往往会设置多个信号量,并且安排不同的初始值,来实现它们之间的执行顺序信号量用于互斥外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

信号量用于同步

二 信号量操作

2.1 信号量初始化

1. #include <semaphore.h>2.intsem_init(sem_t*sem,int pshared,unsignedint value);3. 功能:创建一个信号量并初始化它的值
4. 参数: sem:信号量地址  
        pshared:等于0,信号量在线程间共享;不等于0,信号量在进程共享。
        value:信号量的初始值。
5.返回值:成功返回0,失败返回-1;

2.2 信号量的P操作

1. #include<semaphore.h>2.intsem_wait(sem_t*sem);3. 功能:将信号量的值减1,若信号量的值小于等于0,此函数会引起调用者阻塞
4. 参数:sem:信号量地址
5. 返回值:成功返回0,失败返回-1
#include<semaphore.h>2.intsem_trywait(sem_t*sem);3. 功能:将信号量的值减1,若信号量的值小于等于0,则对信号量的操作失败,函数立即返回
4. 参数:sem:信号量地址
5. 返回值:成功返回0,失败返回-1

2.3 信号量的V操作

1. #include <semaphore.h>2.intsem_post(sem_t*sem)3. 功能:执行v操作,执行一次,信号量的值加14. 参数:sem:信号量地址
5. 返回值:成功返回0,失败返回-1

2.4 获取信号量的计数值

1. #include <semaphore.h>2.intsem_getvalue(sem_t*sem,int*sval);3. 功能:获取sem标识的信号量的值,保存在sval中
4. 参数:sem:信号量地址 sval:保存信号量值的地址
5. 返回值:成功返回0,失败返回-1

2.5 信号量的销毁

1. #include <semaphore.h>2.intsem_destroy(sem_t*sem);3. 功能:删除sem标识的信号量,
4. 参数:sem:信号量地址 
5. 返回值:成功返回0,失败返回-1

三 信号量的使用

3.1 信号量实现互斥功能

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

#include<stdio.h>#include<pthread.h>#include<semaphore.h>#include<unistd.h>#include<stdlib.h>// 通过信号量实现互斥操作// 第一步:创建一个信号量sem_t sem;voidprinter(char*str){//      第三步:执行p操作//      由于使用信号量实现互斥,信号量初始值设置为1,则两个线程执行p操作//      先执行p操作的线程继续执行,后执行p操作的先阻塞等待sem_wait(&sem);while(*str){putchar(*str);fflush(stdout);
                str++;sleep(1);}//      第四步:执行v操作sem_post(&sem);}void*thr_fun1(void*arg){char*str1 ="change";printer(str1);}void*thr_fun2(void*arg){char*str2 ="word";printer(str2);}intmain(){pthread_t th1,th2;//      第二步:初始化信号量sem_init(&sem,0,1);if(pthread_create(&th1,NULL,thr_fun1,NULL)!=0){perror("fail to pthread_create");exit(1);}if(pthread_create(&th2,NULL,thr_fun2,NULL)!=0){perror("fail to pthread_create");exit(1);}pthread_join(th1,NULL);pthread_join(th2,NULL);printf("\n");//      第五步sem_destroy(&sem);return0;}

执行结果

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

3.2 信号量实现同步功能

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

#include<stdio.h>#include<pthread.h>#include<semaphore.h>#include<unistd.h>#include<stdlib.h>// 通过信号量实现同步操作// 第一步:创建两个信号量sem_t sem_p,sem_g;char ch ='a';void*thr_g(void*arg){while(1){//              第四步:执行p功能sem_wait(&sem_g);
                ch++;sleep(1);//              第六步:执行v操作sem_post(&sem_p);}pthread_exit(0);}void*thr_p(void*arg)// 打印ch的值{while(1){//              第三步执行p操作sem_wait(&sem_p);printf("%c",ch);fflush(stdout);//              第五步执行V操作sem_post(&sem_g);}pthread_exit(0);}intmain(){pthread_t th1,th2;//      第二步初始化信号量sem_init(&sem_p,0,1);sem_init(&sem_g,0,0);if(pthread_create(&th1,NULL,thr_p,NULL)!=0){perror("fail to pthread_create");exit(1);}if(pthread_create(&th2,NULL,thr_g,NULL)!=0){perror("fail to pthread_create");exit(1);}pthread_join(th1,NULL);pthread_join(th2,NULL);printf("\n");//      第五步,销毁信号量sem_destroy(&sem_p);sem_destroy(&sem_g);return0;}

本文转载自: https://blog.csdn.net/2403_83472896/article/details/138682002
版权归原作者 yz666^_^ 所有, 如有侵权,请联系我们删除。

“linux_信号量(详解)”的评论:

还没有评论