[<<Previous Entry] [^^Up^^] [Next Entry>>] [Menu] [About The Guide]
 ðÒÏÉÚ×ÏÄÉÔÅÌØ É ðÏÔÒÅÂÉÔÅÌØ ÂÕÆÅÒÁ

ðòïéú÷ïäéôåìø âõæåòá, prod_onebuf.c :

  1 /* producer program:
  2    producer program sets up a buffer to be read by a consumer
  3    semaphores are used to ensure that producer doesn't
  4    overwrite an unread buffer and consumer  doesn't
  5    the same data more than once.
  6 */
  7 #include <sys/types.h>
  8 #include <unistd.h>
  9 #include <stdio.h>
 10 #include <stdlib.h>
 11 #include <sys/ipc.h>
 12 #include <sys/sem.h>
 13 #include <sys/shm.h>
 14 #define MSG_SIZE 30
 15 #define MAX 5
 16
 17 main()
 18 {
 19  key_t key;
 20  /* two semaphores in a set
 21  index 0 -incremented when producer has reset buffer
 22          -tested and decremented by consumer to check
 23              if buffer has been reset
 24  index 1 -incremented when  consumer  has  read buffer
 25          -tested and decremented  by producer to check
 26               if consumer is done
 27  */
 28  static struct sembuf wait_consumed = { 1, -1, 0};
 29  static struct sembuf signal_produced = { 0, 1, 0};
 30  int semid, shmid, i;
 31  char *message;
 32
 33  if((key = ftok( getenv("HOME"), 'u')) == -1){
 34     fprintf(stderr,"ftok key formation error\n");

 35     exit(1);
 36  }
 37
 38  if((semid=semget(key, 2, IPC_CREAT | 0660)) == -1){
 39     perror("producer semget():");
 40     exit(2);
 41  }
 42
 43  if((shmid=shmget(key, MSG_SIZE, IPC_CREAT | 0660)) == -1) {
 44    perror("producer shmget():");
 45    exit(3);
 46  }
 47
 48  message=shmat(shmid, 0, 0);
 49
 50  for(i=1; i < MAX; i++) {
 51     /* producer has to go first */
 52     if(i > 1)
 53         semop(semid,&wait_consumed,1);
 54     sprintf(message, "message %d", i);
 55     semop(semid, &signal_produced, 1);
 56  }
 57  shmdt(message);
 58  sleep(5); /* allow consumer to digest last message */
 59
 60  /* alternatively a DELIMITER string could be placed in
 61     shared memory when seen by the consumer, it would exit.
 62     the producer would do shmctl(...,IPC_STAT,...)
 63     and when shm_attach==1
 64     it would remove the two IPC facilities
 65  */
 66  shmctl(shmid, IPC_RMID, NULL);
 67  semctl(semid, 0, IPC_RMID ,0);
 68 }

ðïôòåâéôåìø âõæåòá, cons_onebuf.c :

  1 /* consumer program:
  2    producer program sets up a buffer to be read by a consumer.
  3    semaphores are used to ensure that producer doesn't

  4     overwrite an unread buffer and consumer doesn't
  5     read the same data more than once.
  6 */
  7 #include <sys/types.h>
  8 #include <stdio.h>
  9 #include <stdlib.h>
 10 #include <sys/ipc.h>
 11 #include <sys/sem.h>
 12 #include <sys/shm.h>
 13 #define MSG_SIZE 30
 14
 15 main(int argc, char *argv[])
 16 {
 17  key_t key;
 18  /* two semaphores in a set
 19  index 0 - incremented when producer  has reset buffer
 20          - tested and decremented by consumer to check
 21              if buffer has been reset
 22  index 1 - incremented  when  consumer has read buffer
 23          - tested and decremented by producer to check
 24              if consumer is done
 25  */
 26  static struct sembuf wait_produced = { 0, -1, 0};
 27  static struct sembuf signal_consumed = { 1, 1, 0};
 28  int semid, shmid, rtn;
 29  char *message;
 30
 31  if((key = ftok( getenv("HOME"), 'u')) == -1){
 32     fprintf(stderr,"ftok key formation error\n");
 33     exit(1);
 34  }
 35
 36  /* either producer or consumer might be the creator
 37     but producer will  be  the  remover  of the IPC resources.
 38     producer and consumer's effective uid must be the same.
 39  */

 40  if ((semid=semget(key, 2, IPC_CREAT | 0660)) == -1) {
 41     perror("consumer semget():");
 42     exit(2);
 43  }
 44
 45  if ((shmid=shmget(key, MSG_SIZE, IPC_CREAT | 0660)) == -1) {
 46     perror("producer shmget():");
 47     exit(3);
 48  }
 49
 50  message=shmat(shmid, (char *)0, SHM_RDONLY);
 51
 52  while(1){
 53     rtn=semop(semid,&wait_produced,1);
 54     /* when producer is done semid will be IPC_RMID forcing break
*/
 55     if(rtn == -1){
 56        perror("consumer - semop on wait_consumed");
 57        break;
 58     }
 59     printf("%s received: %s\n", argv[0], message);
 60     semop(semid, &signal_consumed, 1);
 61  }
 62     shmdt(message);
 63     exit(0);
 64 }

÷ùúï÷:
$ prod_onebuf&
14649
$ cons_onebuf
cons_onebuf received: message 1
cons_onebuf received: message 2
cons_onebuf received: message 3
cons_onebuf received: message 4
consumer-semop on wait_consumed:Identifier removed
$