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 }