• Linux——信号量(定义、示例、信号量接口)


    目录

    1、信号量

    2、信号量举例

    3、信号量的接口

    4、通过控制进程来完成打印机操作

    5、ipcs命令

    1、信号量

    • (1)定义:​​​​​​
    • 信号量是一个特殊的变量,一般取正数值。它的值代表允许访问的资源数目,获取资源时,需要对信号量的值进行原子减一,该操作被称为Р操作。
    • 当信号量值为О时,代表没有资源可用,Р操作会阻塞。释放资源时工需要对信号量的值进行原子加一,该操作被称为V操作。信号量主要用来同步进程。
    • 信号量的值如果只取0,1,将其称为二值信号量。如果信号量的值大于1,则称之为计数信号量。
    • 注意:正数值;加一减一是一个原子操作;
    •      (原子操作:信号量+1 -1,不能被打断)

    (2)临界资源和临界区的概念

    ①临界资源:指计算机的软硬件资源;同一时刻,只允许进程或者线程访问的资源。

    临界区:访问临界资源的代码段。

    2、信号量举例

    • 不加控制模拟使用打印机
    • 题目:进程a和进程b模拟访问访问打印机,进程a输出第一个字符'a'表示开始使用打印机,输出第二个字符’a‘表示结束使用,b进程操作与a进程相同。
    • (由于打印机同一时刻只能被一个进程使用,所以输出结果不应该出现abab这样交替的结果)。

    1. //进程a.c
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include
    7. int main()
    8. {
    9. int i=0;
    10. for(;i<5;i++)
    11. {
    12. printf("A");
    13. fflush(stdout);
    14. int n=rand()%3;
    15. sleep(n);
    16. printf("A");
    17. fflush(stdout);
    18. n=rand()%3;
    19. sleep(n);
    20. }
    21. }
    1. //进程b.c
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include
    7. int main()
    8. {
    9. int i=0;
    10. for(;i<5;i++)
    11. {
    12. printf("B");
    13. fflush(stdout);
    14. int n=rand()%3;
    15. sleep(n);
    16. printf("B");
    17. fflush(stdout);
    18. n=rand()%3;
    19. sleep(n);
    20. }
    21. }

     如果不加控制,两个进程运行结果:

    3、信号量的接口

    (1)semget

    • int semget(key_t key,int nsems,int semflg);//创建或者获取一个已经存在的信号量
    • //key:给相同的key值,能得到相同的信号量
    • //nsems:创建几个信号量;
    • //semflg:标志位;如果为创建:IPC_CREAT;
    • //如果为全新创建,也就是不知道是否有人创建过,则IPC_CREATE|IPC_EXCL,就是如果

             没有则创建,如果有则创建失败 ;

    (2)semop

    • int semop(int semid,struct sembuf *sops,unsigned nsops);//对信号量进行改变,做P操作或者V操作;
    • //semid:信号量的id号,也就是刚才semget的返回值;说明对哪个信号量进行操作;
    • //sops:结构体指针,指向sembuf的结构体指针,sembuf结构体有三个成员变量:

          ①sem_num表示信号量的编号(即指定信号量集中的信号量下标);

          ②sem_op表示是p还是v操作;

          ③1为v操作。

    注意:(加1),-1为p操作(减1);

               sem_flg为标志位;
    (3)semctl

    • int semctl(int semid,int semnum,int cmd,...);//对信号量进行控制:初始化/删除信号量
    • semid:信号量id;
    • semnum:信号量编号;
    • cmd:命令:SETVAL:初始化信号量;
    • IPC_RMID:删除信号量;

    **注意**:联合体semun,这个联合体需要自己定义;

    4、通过控制进程来完成打印机操作

    (不存在abab交替打印)

    思路: 在打印前进行p操作和v操作。

    5、ipcs命令

    • (1)查看信号量和消息队列,共享内存:ipcs
    • (2)只查看所有的信号量:ipcs -s
    • (3)只查看所有的共享内存:ipcs -m
    • (4)显示所有消息队列:ipcs -q
    • (5)显示最近访问过IPC设施的进程ID ipcs -p ipcs -m -p ipcs -q -p
    • (6)显示IPC设施的最后操作时间

                     ipcs -t

                     ipcs -q -t

                     ipcs -m -t

                     ipcs -s -t

    • (7)显示IPC设施的当前状态

                      ipcs -u

    • (8)显示IPC设施的权限关系

                      ipcs -c

                      ipcs -m -c

                      ipcs -q -c

                      ipcs -s -c

    • (9)显示IPC设施的详细信息

                      ipcs -q -i id

     注意:id 对应shmid、semid、msgid等。-q对应设施的类型(队列),查看信号量详细情况使用-s,查看共享内存使用-m。

    • (10)显示所有的IPC设施

                      ipcs -a

    如有错误,敬请指正。

    您的收藏与点赞都是对我最大的鼓励和支持!

  • 相关阅读:
    【Linux】grep显示行号的时候,冒号和减号的区别
    学生护眼台灯哪个牌子最好?2022双十二4款儿童护眼写字灯推荐
    第五届传智杯-初赛【A组-题解】
    模板再认识
    RK3588平台开发系列讲解(Thermal篇)Thermal的设备树配置
    数据结构——栈和队列
    统计单词数量(文件)(*)
    【算法】spfa算法求最短路(没有负环)
    spring---第六篇
    QT4到QT5移植出现的一些问题
  • 原文地址:https://blog.csdn.net/x20020402/article/details/127686343