1. 程式人生 > 其它 >linux網路程式設計-程序間通訊——訊號量

linux網路程式設計-程序間通訊——訊號量

  1 #include<sys/types.h>
  2 #include<sys/ipc.h>
  3 #include<sys/sem.h>
  4 #include <stdio.h>
  5 #include <stdlib.h>
  6 #include<errno.h>
  7 
  8 int gSemid = 0;
  9 typedef int sem_t;
 10 #define ERR_EXIT(m) \
 11         do \
 12         { \
 13             perror(m); \
14 exit(EXIT_FAILURE); \ 15 }while(0) 16 17 sem_t CreateSem(key_t key, int value) 18 { 19 union semun sem; 20 sem_t semid; 21 sem.val = value; 22 23 semid = semget(key, 1, IPC_CREAT | IPC_EXCL | 0666);//建立訊號量個數為1 24 if(-1 == semid) 25 { 26 ERR_EXIT("
semget"); 27 } 28 semctl(semid, 0, SETVAL, sem);//引數2-要操作的訊號量在訊號量集中的編號;引數3-cmd... 29 30 return semid; 31 } 32 33 int Sem_P(sem_t semid) 34 { 35 //sops有三種方式,0-預設阻塞、IPC_NOWAIT-非阻塞、SEM_UNDO-撤銷上一次操作 36 struct sembuf sops={0,-1,0}; 37 return (semop(semid,&sops,1)); 38
} 39 40 int Sem_V(sem_t semid) 41 { 42 struct sembuf sops={0,+1,0}; 43 return (semop(semid,&sops,1)); 44 } 45 46 void SetvalueSem(sem_t semid, int value) 47 { 48 union semun sem; 49 sem.val = value; 50 51 semctl(semid,0,SETVAL,sem); 52 } 53 54 int GetvalueSem(sem_t semid) 55 { 56 union semun sem; 57 return semctl(semid,0,GETVAL,sem); 58 } 59 60 void DestroySem(sem_t semid) 61 { 62 union semun sem; 63 sem.val = 0; 64 semctl(semid,0,IPC_RMID,sem); 65 } 66 67 void Print(char opChar) 68 { 69 int pauseTime; 70 srand(getpid()); 71 int i; 72 73 for(i=0; i<10; i++) 74 { 75 if(Sem_P(gSemid) != 0) 76 ERR_EXIT("Sem_P"); 77 //臨界區-begin 78 printf("%c", opChar); 79 fflush(stdout); 80 pauseTime = rand()%3; 81 sleep(pauseTime); 82 printf("%c", opChar); 83 fflush(stdout); 84 //臨界區-end 85 Sem_V(gSemid); 86 pauseTime = rand()%2; 87 sleep(pauseTime); 88 } 89 } 90 91 int main(void) 92 { 93 char i; 94 key_t key; 95 int value = 0; 96 int pid; 97 98 key = ftok("./ipc", 'c'); 99 gSemid = CreateSem(key,1); 100 101 value = GetvalueSem(gSemid); 102 printf("訊號量值 = %d\n",value); 103 104 pid = fork(); 105 if(-1 == pid) 106 { 107 ERR_EXIT("fork"); 108 } 109 110 if(pid > 0)//父程序 111 { 112 Print('o'); 113 wait(NULL);//等待子程序推出,刪除訊號量集 114 DestroySem(gSemid); 115 }else//子程序 116 { 117 Print('x'); 118 } 119 120 #if 0 121 for(i = 0; i<105; i++) 122 { 123 if(Sem_P(gSemid) != 0) 124 ERR_EXIT("Sem_P"); 125 126 value = GetvalueSem(gSemid); 127 printf("訊號量值 = %d\n",value); 128 129 Sem_V(gSemid); 130 //value = GetvalueSem(semid); 131 //printf("訊號量值 = %d\n",value); 132 } 133 #endif 134 135 return 0; 136 }