分享

Linux多线程编程-信号量

 wusiqi111 2017-10-09

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

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多