Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 274|回复: 0

[默认分类] Linux多线程编程-信号量

[复制链接]
  • TA的每日心情
    开心
    2021-12-13 21:45
  • 签到天数: 15 天

    [LV.4]偶尔看看III

    发表于 2018-7-10 13:37:55 | 显示全部楼层 |阅读模式

             在Linux中,信号量API有两组,一组是多进程编程中的System V IPC信号量;另外一组是我们要讨论的POSIX信号量。这两组接口类似,但不保证互换。POSIX信号量函数都已sem_开头,并不像大多数线程函数那样以pthread_开头,常用的有以下5个:

    1. #include <semaphore.h>
    2. int sem_init(sem_t* sem, int pshared, unsigned int value);
    3. int sem_destroy(sem_t *sem);
    4. int sem_wait(sem_t *sem);
    5. int sem_trywait(sem_t *sem);
    6. int sem_post(sem_t *sem);
    复制代码

             这些函数的第一个参数sem指向被操作的信号量,上面这些函数成功时返回0,失败返回-1并设置errno。
    l  sem_init函数用于初始化一个未命名的信号量(POSIX信号量API支持命名信号量,不过在该章节没有讨论)。pshared制定信号量的类型,如果其值为0,则表示这个信号量是当前进程的局部信号量,否则信号量就可以在多个进程之间共享。value制定信号量的初始值,此外初始化一个已经被初始化的信号量将导致不可预期的后果
    l  sem_destroy用于销毁信号量,以释放其占用的内核资源。如果销毁一个正在等待的信号量,则将导致不可预期的后果
    l  sem_wait以原子操作将信号量值减1,如果信号量的值为0,则sem_wait将被阻塞,直到该信号量值为非0值
    l  sem_trywait与sem_wait函数类似,不过它始终立即返回,而不论信号量是否具有非0值,相当于sem_wait的非阻塞版本。当信号量的值为非0时,sem_trywait对信号量执行减1操作;当信号量为0时,它将返回-1并设置errno为EAGAIN
    l  sem_post以原子操作的方式将信号量的值加1,当信号量的值大于0时,其他正在调用sem_wait等待信号量的线程将被唤醒


    线程中使用信号量示例

    1. #include <stdio.h>
    2. #include <stdlib.h>
    3. #include <semaphore.h>
    4. #include <pthread.h>
    5. #define err_sys(msg) \
    6.         do { perror(msg); exit(-1); } while(0)
    7. #define err_exit(msg) \
    8.         do { fprintf(stderr, msg); exit(-1); } while(0)
    9. void *r1(void *arg)
    10. {
    11.         sem_t* sems = (sem_t *)arg;
    12.         static int cnt = 10;
    13.         while(cnt--)
    14.         {
    15.                 sem_wait(sems);
    16.                 printf("I am in r1. I get the sems.\n");
    17.         }
    18. }
    19. void *r2(void *arg)
    20. {
    21.         sem_t* sems = (sem_t *)arg;
    22.         static int cnt = 10;
    23.         while(cnt--)
    24.         {
    25.                 printf("I am in r2. I send the sems\n");
    26.                 sem_post(sems);
    27.                 sleep(1);
    28.         }
    29. }
    30. int main(void)
    31. {
    32.         sem_t sems;
    33.         pthread_t t1, t2;
    34.        
    35.         printf("sems size: %d\n", sizeof(sems));
    36.         /* sem_init()第二个参数为0表示这个信号量是当前进程的局部信号量,否则该信号
    37.          * 就可以在多个进程之间共享 */
    38.         if(sem_init(&sems, 0, 0) < 0)
    39.                 err_sys("sem_init error");
    40.         pthread_create(&t1, NULL, r1, &sems);
    41.         pthread_create(&t2, NULL, r2, &sems);
    42.         pthread_join(t1, NULL);
    43.         pthread_join(t2, NULL);
    44.         sem_destroy(&sems);
    45.         return 0;
    46. }
    复制代码

    参考:

             1、《Linux高性能服务器编程》第14章 多线程编程/信号量


    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-4-25 01:29 , Processed in 0.378864 second(s), 37 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表