信号量
/* * semgTest.cpp * * Created on: Jun 27, 2013 * Author: zsf */ #include "semgTest.h" //联合类型semun定义 union semun { int val; struct semid_ds *buf; unsigned short *array; }; //函数声明 //函数:设置信号量的值 static int set_semvalue(void); //函数:删除信号量 static void del_semvalue(void); //函数:信号量P操作 static int semaphore_p(void); //函数:信号量V操作 static int semaphore_v(void); static int sem_id;//信号量ID int main(int argc, char *argv[]) { int i; int pause_time; char op_char = 'O'; srand((unsigned int) getpid()); //创建一个新的信号量或者是取得一个已有信号量的键 sem_id = semget((key_t) 1234, 1, 0666 | IPC_CREAT); //如果参数数量大于1,则这个程序负责创建信号和删除信号量 if (argc > 1) { if (!set_semvalue()) { fprintf(stderr, "failed to initialize semaphore\n"); exit(EXIT_FAILURE); } op_char = 'X';//对进程进行标记 sleep(5); } //循环:访问临界区 for (i = 0; i < 10; ++i) { //P操作,尝试进入缓冲区 if (!semaphore_p()) exit(EXIT_FAILURE); printf("%c", op_char); fflush(stdout);//刷新标准输出缓冲区,把输出缓冲区里的东西打印到标准输出设备上 pause_time = rand() % 3; sleep(pause_time); printf("%c", op_char); fflush(stdout); //V操作,尝试离开缓冲区 if (!semaphore_v()) exit(EXIT_FAILURE); pause_time = rand() % 2; sleep(pause_time); } printf("\n %d - finished \n", getpid()); if (argc > 1) { sleep(10); del_semvalue();//删除信号量 } } //函数:设置信号量的值 static int set_semvalue(void) { union semun sem_union; sem_union.val = 1; if (semctl(sem_id, 0, SETVAL, sem_union)) return 0; return 1; } //函数:删除信号量 static void del_semvalue(void) { union semun sem_union; if (semctl(sem_id, 0, IPC_RMID, sem_union)) fprintf(stderr, "Failed to delete semaphore\n"); } //函数:信号量P操作:对信号量进行减一操作 static int semaphore_p(void) { struct sembuf sem_b; sem_b.sem_num = 0;//信号量编号 sem_b.sem_op = -1;//P操作 sem_b.sem_flg = SEM_UNDO; if (semop(sem_id, &sem_b, 1) == -1) { fprintf(stderr, "semaphore_p failed\n"); return 0; } return 1; } //函数:信号量V操作:对信号量进行加一操作 static int semaphore_v(void) { struct sembuf sem_b; sem_b.sem_num = 0;//信号量编号 sem_b.sem_op = 1;//V操作 sem_b.sem_flg = SEM_UNDO; if (semop(sem_id, &sem_b, 1) == -1) { fprintf(stderr, "semaphore_v failed\n"); return 0; } return 1; }
1 /*
2 * semtest.cpp
3 *
4 * Created on: Jun 27, 2013
5 * Author: zsf
6 */
7
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <sys/types.h>
11 #include <sys/ipc.h>
12 #include <sys/sem.h>
13 #include <sys/stat.h>
14 #include <fcntl.h>
15 #include <unistd.h>
16 #include <string.h>
17 #include <strings.h>
18
19 union semun {
20 int val;
21 struct semid_ds *buf;
22 unsigned short int *array;
23 struct seminfo *__buf;
24 };
25
26 int main(void) {
27 char* buf_child[] = { "this", "is", "the", "child", "process" };
28 char* buf_father[] = { "father", "say", "hello", "to", "child" };
29 int i = 0, semid, fd;
30 pid_t pid;
31 struct sembuf sb; //信号量操作
32 union semun sem;
33 semid = semget(1000, 2, 0666 | IPC_CREAT); //申请信号量组,包含2个信号量
34
35 sem.val = 0;
36 semctl(semid, 0, SETVAL, sem); //初始化0号信号量为0
37 sem.val = 1;
38 semctl(semid, 1, SETVAL, sem); //初始化1号信号量为1
39
40 fd = open("./tmp", O_CREAT | O_TRUNC | O_WRONLY, 0666);
41
42 pid = fork();
43 switch (pid) {
44 case -1:
45 perror("fork fail");
46 break;
47 case 0: /* child consume */
48 srand((unsigned int) getpid());
49 while (i < 5) {
50 sb.sem_num = 1; //将1号信号量
51 sb.sem_op = -1; //减1
52 sb.sem_flg = sb.sem_flg & ~IPC_NOWAIT;
53 semop(semid, &sb, 1);
54
55 write(fd, buf_child[i], strlen(buf_child[i]));
56 sleep(rand());
57 write(fd, &" ", 1);
58 i++;
59
60 sb.sem_num = 0; //将0号信号量
61 sb.sem_op = 1; //加1
62 sb.sem_flg = sb.sem_flg & ~IPC_NOWAIT;
63 semop(semid, &sb, 1); //操作信号量
64 }
65 break;
66 default:/* parent production */
67 srand((unsigned int) getpid());
68 while (i < 5) {
69 sb.sem_num = 0; //将0号信号量
70 sb.sem_op = -1; //减1
71 sb.sem_flg = sb.sem_flg & ~IPC_NOWAIT;
72 semop(semid, &sb, 1); //操作信号量
73
74 write(fd, buf_father[i], strlen(buf_father[i]));
75 sleep(rand());
76 write(fd, &" ", 1);
77 i++;
78
79 sb.sem_num = 1;
80 sb.sem_op = 1;
81 sb.sem_flg = sb.sem_flg & ~IPC_NOWAIT;
82 semop(semid, &sb, 1);
83 }
84 break;
85 }
86 return 0;
87 }
2 * semtest.cpp
3 *
4 * Created on: Jun 27, 2013
5 * Author: zsf
6 */
7
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <sys/types.h>
11 #include <sys/ipc.h>
12 #include <sys/sem.h>
13 #include <sys/stat.h>
14 #include <fcntl.h>
15 #include <unistd.h>
16 #include <string.h>
17 #include <strings.h>
18
19 union semun {
20 int val;
21 struct semid_ds *buf;
22 unsigned short int *array;
23 struct seminfo *__buf;
24 };
25
26 int main(void) {
27 char* buf_child[] = { "this", "is", "the", "child", "process" };
28 char* buf_father[] = { "father", "say", "hello", "to", "child" };
29 int i = 0, semid, fd;
30 pid_t pid;
31 struct sembuf sb; //信号量操作
32 union semun sem;
33 semid = semget(1000, 2, 0666 | IPC_CREAT); //申请信号量组,包含2个信号量
34
35 sem.val = 0;
36 semctl(semid, 0, SETVAL, sem); //初始化0号信号量为0
37 sem.val = 1;
38 semctl(semid, 1, SETVAL, sem); //初始化1号信号量为1
39
40 fd = open("./tmp", O_CREAT | O_TRUNC | O_WRONLY, 0666);
41
42 pid = fork();
43 switch (pid) {
44 case -1:
45 perror("fork fail");
46 break;
47 case 0: /* child consume */
48 srand((unsigned int) getpid());
49 while (i < 5) {
50 sb.sem_num = 1; //将1号信号量
51 sb.sem_op = -1; //减1
52 sb.sem_flg = sb.sem_flg & ~IPC_NOWAIT;
53 semop(semid, &sb, 1);
54
55 write(fd, buf_child[i], strlen(buf_child[i]));
56 sleep(rand());
57 write(fd, &" ", 1);
58 i++;
59
60 sb.sem_num = 0; //将0号信号量
61 sb.sem_op = 1; //加1
62 sb.sem_flg = sb.sem_flg & ~IPC_NOWAIT;
63 semop(semid, &sb, 1); //操作信号量
64 }
65 break;
66 default:/* parent production */
67 srand((unsigned int) getpid());
68 while (i < 5) {
69 sb.sem_num = 0; //将0号信号量
70 sb.sem_op = -1; //减1
71 sb.sem_flg = sb.sem_flg & ~IPC_NOWAIT;
72 semop(semid, &sb, 1); //操作信号量
73
74 write(fd, buf_father[i], strlen(buf_father[i]));
75 sleep(rand());
76 write(fd, &" ", 1);
77 i++;
78
79 sb.sem_num = 1;
80 sb.sem_op = 1;
81 sb.sem_flg = sb.sem_flg & ~IPC_NOWAIT;
82 semop(semid, &sb, 1);
83 }
84 break;
85 }
86 return 0;
87 }