[<<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.
$