linux 信号量(进程间通信)

来源:互联网 发布:数据酋长 ebay分析 编辑:程序博客网 时间:2024/06/05 06:59

http://blog.csdn.net/hubi0952/article/details/7971342

将使用一个程序来演示信号量的使用,程序用PV操作控制信号量,以操作临界区,P操作让信号量减1,V操作让信号量加1,而PV操作之间的代码即为临界区关键代码。每次只能由一个进程访问。

程序创建出一个子进程,在两个进程中分别有一段临界区关键代码,实现的功能都是不断的顺序输出0~9的字符。

保证进程间同步

[plain] view plaincopyprint?
  1. #include <unistd.h>  
  2. #include <stdlib.h>  
  3. #include <stdio.h>  
  4. #include <sys/types.h>  
  5. #include <sys/ipc.h>  
  6. #include <sys/sem.h>  
  7.   
  8. static int init_semvalue (int);  
  9. static void del_semvalue (int);  
  10. static int P (int);  
  11. static int V (int);  
  12.   
  13. //自己定义的semun结构体  
  14. union semun  
  15. {  
  16.   int val;  
  17.   struct semid_ds *buf;  
  18.   unsigned short *array;  
  19.   struct seminfo *__buf;  
  20. };  
  21.   
  22. int  
  23. main (int argc, char *argv[])  
  24. {  
  25.   int var_cri = 0;  
  26.   int sem_id;  
  27.   pid_t pid;  
  28.   
  29.   //创建一个信号量  
  30.   sem_id = semget ((key_t) 2234, 1, 0666 | IPC_CREAT);  
  31.   //初始化一个信号量  
  32.   if (!init_semvalue (sem_id))  
  33.     {  
  34.       fprintf (stderr, "Failed to initialize semaphore!\n");  
  35.       exit (EXIT_FAILURE);  
  36.     }  
  37.   //创建子进程  
  38.   if ((pid = fork ()) == 0) //子进程  
  39.     {  
  40.       while (1)  
  41.     {  
  42.           //临界区  
  43.       if (!P (sem_id))//申请资源  
  44.         exit (EXIT_FAILURE);  
  45.       int i;  
  46.       for (i = 0; i != 10; ++i)  
  47.         {  
  48.           printf ("[child]: %d\n", i);  
  49.           sleep (1);  
  50.         }  
  51.       if (!V (sem_id))//释放资源  
  52.         exit (EXIT_FAILURE);  
  53.     }  
  54.     }  
  55.   else if (pid > 0)      //父进程  
  56.     {  
  57.       sleep (2);  
  58.       while (1)  
  59.     {  
  60.           //临界区  
  61.       if (!P (sem_id))  
  62.         exit (EXIT_FAILURE);  
  63.       int i;  
  64.       for (i = 0; i != 10; ++i)  
  65.         {  
  66.           printf ("[parent]: %d\n", i);  
  67.           sleep (1);  
  68.         }  
  69.       if (!V (sem_id))  
  70.         exit (EXIT_FAILURE);  
  71.     }  
  72.       sleep (8);  
  73.       //销毁信号量  
  74.       del_semvalue (sem_id);  
  75.     }  
  76.   exit (EXIT_SUCCESS);  
  77. }  
  78.   
  79.   
  80. static int  
  81. init_semvalue (int id)  
  82. {  
  83.   union semun sem_union;  
  84.   sem_union.val = 1;  
  85.   if (semctl (id, 0, SETVAL, sem_union) == -1)//设置信号量集中的信号量值value  
  86.     return (0);  
  87.   return (1);  
  88. }  
  89.   
  90. static void  
  91. del_semvalue (int id)  
  92. {  
  93.   union semun sem_union;  
  94.   if (semctl (id, 0, IPC_RMID, sem_union) == -1)//IPC——RMID将信号量集从内存中删除  
  95.     fprintf (stderr, "Failed to delete semaphore\n");  
  96. }  
  97.   
  98. int  
  99. P (int id)  
  100. {  
  101.   struct sembuf op;  
  102.   
  103.   op.sem_num = 0;//单信号  
  104.   op.sem_op = -1;//P操作  
  105.   op.sem_flg = 0;  
  106.   if (semop (id, &op, 1) < 0)//改变key,它代表进程要使用的某个资源  
  107.     return 0;  
  108.   return 1;  
  109. }  
  110.   
  111. int  
  112. V (int id)  
  113. {  
  114.   struct sembuf op;  
  115.   
  116.   op.sem_num = 0;  
  117.   op.sem_op = 1;//V操作  
  118.   op.sem_flg = 0;  
  119.   if (semop (id, &op, 1) < 0)  
  120.     return 0;  
  121.   return 1;  


0 0