[<<Previous Entry]
[^^Up^^]
[Next Entry>>]
[Menu]
[About The Guide]
ïÄÉÎ ÐÒÏÉÚ×ÏÄÉÔÅÌØ É ÎÅÓËÏÌØËÏ ÐÏÔÒÅÂÉÔÅÌÅÊ
ðòïéú÷ïäéôåìø, ðéûõýéê ÷ âõæåò äìñ îåóëïìøëéè ðïôòåâéôåìåê
shm_wall_s.c :
1 #include <stdio.h>
2 #include <sys/types.h>
3 #include <unistd.h>
4 #include <stdlib.h>
5 #include <sys/ipc.h>
6 #include <sys/shm.h>
7 #include <sys/sem.h>
8 #include <errno.h>
9 #include <string.h>
10
11 /*
12 * shm_wall_s n_rcvrs
13 * take string from stdin and put into shared mem, wait for
14 * all n_rcvrs to take it out.
15 *
16 * Producer: Consumer:
17 *
18 * wait for NLEFT=0; wait for NLEFT>0, --;
19 * Produce Consume
20 * NLEFT=n_rcvrs; wait for NLEFT=0;
21 * wait for NTAKEN=n_rcvrs,NTAKEN=0;i increment NTAKEN;
22 */
23
24 #define NLEFT 0
25 #define NTAKEN 1
26
27 static struct sembuf wait_NLEFT_0 = { NLEFT, 0, 0};
28
29
30 main(int argc, char *argv[])
31 {
32 key_t shmkey;
33 struct sembuf sem_buffer;
34 char buffer[128], *shared;
35 short n_rcvrs;
36 int shmid, semid, done;
37
38
39 if ( argc < 2 ) {
40 fprintf(stderr,"Usage: %s n_rcvrs\n", argv[0]);
41 exit(1);
42 }
43
44 sscanf(argv[1], "%hd", &n_rcvrs);
45
46 setbuf(stdout, 0); /* no buffering */
47
48 printf("producer starting, expecting %d consumers.\n",
49 n_rcvrs);
50
51 shmkey = ftok("shm_wall_s.c", 'm');
52 if (shmkey == -1) {
53 fprintf(stderr, "Producer can't get key.\n");
54 exit(1);
55 }
56
57 shmid = shmget(shmkey, 1024, 0640 | IPC_CREAT );
58 if (shmid == -1) {
59 perror("Producer can't get shared memory");
60 exit(2);
61 }
62
63 shared = shmat(shmid, NULL, 0);
64 if (shared == (char *) -1) {
65 perror("Producer can't shmat memory");
66 exit(3);
67 }
68
69 semid = semget(shmkey,2,0640|IPC_CREAT);
70 if (semid == -1) {
71 perror("Producer can't get semaphores");
72 exit(4);
73 }
74
75 semctl(semid, NLEFT, SETVAL, 0);
76 semctl(semid, NTAKEN, SETVAL, 0);
77
78 done = 0;
79 while(!done) {
80 if (semop(semid, &wait_NLEFT_0,1)==-1) {
81 perror( "Producer waits for NLEFT=0");
82 exit(5);
83 }
84
85
86 printf("Enter message to be broadcast:");
87 if (gets(buffer) == NULL) {
88 buffer[0] = '\0';
89 done++;
90 printf("\nProducer producing EOF.\n");
91 }
92 else printf("\nProducer producing \"%s\".\n", buffer);
93 strcpy(shared, buffer); /* Produce */
94
95 sem_buffer.sem_num = NLEFT;
96 sem_buffer.sem_op = n_rcvrs;
97 sem_buffer.sem_flg = 0;
98 if (semop(semid, &sem_buffer, 1) == -1) {
99 perror("Producer sets NLEFT = n_rcvrs");
100 exit(6);
101 }
102
103 sem_buffer.sem_num = NTAKEN;
104 sem_buffer.sem_op = -n_rcvrs;
105 sem_buffer.sem_flg = 0;
106 if (semop(semid, &sem_buffer, 1) == -1) {
107 perror("Producer waits for NTAKEN = ncvr_s");
108 exit(4);
109 }
110 }
111
112 sleep(4); /* give others a chance to die first */
113
114 semctl(semid, 0, IPC_RMID, 0);
115 shmdt(shared);
116 shmctl(shmid, IPC_RMID, 0);
117 }
ðïôòåâéôåìé, þéôáàýéå éú âõæåòá, shm_wall_r1.c
1 #include <stdio.h>
2 #include <sys/types.h>
3 #include <unistd.h>
4 #include <stdlib.h>
5 #include <sys/ipc.h>
6 #include <sys/shm.h>
7 #include <sys/sem.h>
8 #include <errno.h>
9 #include <string.h>
10
11 /*
12 * shm_wall_r: consume stuff from multiple send and print it.
13 *
14 * Producer: Consumer:
15 *
16 * wait for NLEFT=0; wait for NLEFT>0, --;
17 * Produce Consume
18 * NLEFT=n_rcvrs; wait for NLEFT=0;
19 * wait for NTAKEN=n_rcvrs,NTAKEN=0; increment NTAKEN;
20 */
21
22 #define NLEFT0
23 #define NTAKEN1
24 static struct sembuf wait_NLEFT_0 = { NLEFT, 0, 0};
25
26 main(int argc, char *argv[])
27 {
28 key_t shmkey;
29 struct sembuf sem_buffer;
30 char buffer[128], *shared;
31 int shmid, semid, done;
32
33 printf("consumer %s starting.\n", argv[0]);
34
35 shmkey = ftok("shm_wall_s.c", 'm');
36 if (shmkey == -1) {
37 fprintf(stderr, "cant get key.\n");
38 exit(1);
39 }
40
41 shmid = shmget(shmkey, 1024, 0640 | IPC_CREAT );
42 if (shmid == -1) {
43 fprintf(stderr,"Consumer can't get shared memory.\n");
44 exit(2);
45 }
46
47 if ((shared=shmat(shmid, NULL, 0)) == (char *) -1){
48 perror("Consumer can't shmat memory");
49 exit(3);
50 }
51
52 semid = semget(shmkey, 2, 0640 | IPC_CREAT );
53 if (semid == -1) {
54 perror("Consumer can't get semaphores");
55 exit(4);
56 }
57
58 done = 0;
59 while (!done) {
60 sem_buffer.sem_num = NLEFT;
61 sem_buffer.sem_op = -1;
62 sem_buffer.sem_flg = 0;
63 if (semop(semid, &sem_buffer, 1) == -1) {
64 perror("Consumer semop -1 on NLEFT");
65 exit(5);
66 }
67
68 strcpy(buffer, shared);/* consume */
69 if (buffer[0] == '\0') {
70 printf("Consumer %s got EOF.\n", argv[0]);
71 done = 1;
72 }
73 else printf("consumer %s got '%s'.\n",
74 argv[0], buffer);
75
76 if (semop(semid, &wait_NLEFT_0, 1) == -1) {
77 perror("Consumer waits for NLEFT = 0");
78 exit(6);
79 }
80
81 sem_buffer.sem_num = NTAKEN;
82 sem_buffer.sem_op = 1;
83 sem_buffer.sem_flg = 0;
84 if (semop(semid, &sem_buffer, 1) == -1) {
85 perror("Consumer semop +1 on NTAKEN");
86 exit(7);
87 }
88 }
89
90 shmdt(shared);
91 }
÷ùúï÷:
$ shm_wall_r1&
3624
$ shm_wall_r2&
3641
$ shm_wall_s 2
producer starting, expecting 2 consumers.
Enter message to be broadcast: hello
Producer producing "hello".
Enter message to be broadcast: to all consumers
Producer producing "to all consumers".
Enter message to be broadcast: <CTRL D>
Producer producing EOF.
consumer shm_wall_r2 starting.
consumer shm_wall_r2 got 'hello'.
consumer shm_wall_r2 got 'to all consumers'.
Consumer shm_wall_r2 got EOF.
consumer shm_wall_r1 starting.
consumer shm_wall_r1 got 'hello'.
consumer shm_wall_r1 got 'to all consumers'.
Consumer shm_wall_r1 got EOF.
$