LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1469|回复: 4

请问消息队列比运用管道有什么优势?

[复制链接]
发表于 2004-2-10 20:56:08 | 显示全部楼层 |阅读模式
请大家原谅我的难处,消息队列和信号量在书的例子很少,在《APUE》没有足够的例子,现在用法大概懂,但感觉很模糊,不好理解(参数)多,去网上搜那些例子太长了。看不明白。。请大家帮我解释一下和贴些简单的例子出来,拜托了。。。

还有个问题,为什么很多例子都是说客户机和服务器间的编程?帮帮忙呀。 :eek: :eek: :confused:
 楼主| 发表于 2004-2-10 21:20:23 | 显示全部楼层
自己先贴些源码,为了方便看,在控制终端看不舒服

  1. /* (c) Louis Granboulan 2000-2003 */
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <unistd.h>
  6. #include <signal.h>
  7. #include <sys/types.h>
  8. #include <sys/ipc.h>
  9. #include <sys/shm.h>
  10. #include <sys/sem.h>

  11. /*
  12. * La file est cha頽閑
  13. * Un maillon contient
  14. *   [ shmid du maillon suivant ; debut, fin, tableau de requetes ]
  15. *   le dernier maillon pointe sur lui-m阭e...
  16. * Par rapport àl'exercice 1, enfile/defile a comme unique argument variable
  17. *   le shmid du maillon courant.
  18. *   NB: il n'est pas optimal de faire un lock àchaque acc鑣,
  19. *   il vaudrait mieux que le s閙aphore indique le nombre de maillons.
  20. * Autre diff閞ence : ce n'est plus le p鑢e qui supprime les IPC lorsque
  21. *   le programme finit, mais le fils defileur.
  22. */
  23. #define TAILLE 10
  24. struct requete { int code, valeur; };
  25. struct maillon { int next; int debut, fin; struct requete tab[TAILLE]; };
  26. int enfile(void);
  27. int defile(void);
  28. void ipcrm(int shmid, int semid, struct maillon *ici);
  29. void sondied(int sig);
  30. void ipcclean(int sig);
  31.                                                                                                 
  32. static struct sembuf op_lock[2] = {
  33.         { 0,  0, 0 },
  34.         { 0,  1, SEM_UNDO },
  35. };
  36.                                                                                                 
  37. static struct sembuf op_unlock[1] = {
  38.         { 0, -1, (IPC_NOWAIT | SEM_UNDO) },
  39. };
  40.                                                                                                 
  41. int loop = 1;
  42. /* Les trois suivantes sont globales pour 阾re accessible de "ipcclean" */
  43. int shmid; /* bloc de m閙oire partag閑 */
  44. int semid; /* s閙aphore */
  45. struct maillon *ici; /* maillon courant */
  46. int main(int argc, char **argv)
  47. {
  48.   int pidenfile, piddefile;
  49.   semid = semget(IPC_PRIVATE,1,IPC_CREAT|SHM_R|SHM_W);
  50.   if (semid==-1) { perror("semget"); exit(1); }
  51.   shmid = shmget(IPC_PRIVATE, sizeof(struct maillon), IPC_CREAT|SHM_R|SHM_W);
  52.   if (shmid==-1) { perror("shmget"); semctl(semid,0,IPC_RMID,0); exit(1); }
  53.   ici = (struct maillon *) shmat(shmid,0,SHM_SHARE_MMU);
  54.            [SIZE=4] /* SHM_SHAPE_MMU 是什么意思? */[/size]
  55.   if (ici==0) {
  56.     perror("shmat");
  57.     if (semctl(semid,0,IPC_RMID,0)) { perror("semctl"); }
  58.     if (shmctl(shmid,IPC_RMID,0)) { perror("shmctl"); }
  59.     exit(1);
  60.   }
  61.   ici->next = shmid;
  62.   ici->debut = ici->fin = 0;
  63.   pidenfile = fork();
  64.   if (pidenfile<0) { perror("fork"); ipcrm(shmid,semid,ici); exit(1); }
  65.   if (!pidenfile) {
  66.     puts("Je suis le fils qui enfile");
  67.     for ( ; ; ) {
  68.       sleep(3600);
  69.       if (enfile()) { puts("File pleine"); exit(1); }
  70.     }
  71.     exit(0);
  72.   }
  73.   piddefile = fork();
  74.   if (piddefile<0) { perror("fork"); ipcrm(shmid,semid,ici); exit(1); }
  75.   if (!piddefile) {
  76.     puts("Je suis le fils qui defile");
  77.     signal(SIGQUIT,ipcclean);
  78.     signal(SIGTERM,ipcclean);
  79.     signal(SIGINT,ipcclean);
  80.     for ( ; ; ) {
  81.       sleep(3600);
  82.       if (defile()) { puts("File vide"); ipcrm(shmid,semid,ici); exit(1); }
  83.     }
  84.     ipcrm(shmid,semid,ici);
  85.     exit(0);
  86.   }
  87.   signal(SIGCHLD,sondied);
  88.   signal(SIGQUIT,sondied);
  89.   signal(SIGTERM,sondied);
  90.   signal(SIGINT,sondied);
  91.   while (loop) {
  92.     char buffer[80]; fgets(buffer,80,stdin);
  93.     switch (buffer[0]) {
  94.     case '>':
  95.       kill(pidenfile,SIGALRM);
  96.       break;
  97.     case '<':
  98.       kill(piddefile,SIGALRM);
  99.       break;
  100.     default:
  101.       puts("Quit");
  102.       loop = 0;
  103.     }
  104.   }
  105.   kill(pidenfile,SIGTERM);
  106.   kill(piddefile,SIGTERM);
  107.   /* ipcrm(shmid,semid,ici);  C'est le fils qui d閒ile qui s'en charge */
  108.   return 0;
  109. }
  110. void sondied(int sig) { loop = 0; }
  111. void ipcclean(int sig) { ipcrm(shmid, semid, ici); }
  112.                                                                                                 
  113. void ipcrm(int shmid, int semid, struct maillon *ici)
  114. {
  115.   int next;
  116.   if (semctl(semid,0,IPC_RMID,0)) { perror("semctl"); }
  117.   while (ici && ici->next != shmid) {
  118.     next = ici->next;
  119.     shmdt((void*)ici);
  120.     if (shmctl(shmid,IPC_RMID,0)) { perror("shmctl"); }
  121.     shmid = next;
  122.   }
  123.   if (ici) shmdt((void*)ici);
  124.   if (shmctl(shmid,IPC_RMID,0)) { perror("shmctl"); }
  125. }
  126.                                                                                                 
  127. int enfile()
  128. {
  129.   int shmnew;
  130.   puts("Enfile");
  131.   if (semop(semid, op_lock, 2) < 0) { perror("semop"); exit(1); }
  132.   ici->fin++;
  133.   if (ici->fin == TAILLE) {
  134.     puts("Cr閍tion d'un maillon");
  135.     shmnew = shmget(IPC_PRIVATE, sizeof(struct maillon), IPC_CREAT|SHM_R|SHM_W);
  136.     if (shmnew==-1) {
  137.       perror("shmget");
  138.       ipcrm(shmid, semid, ici);
  139.       exit(1);
  140.     }
  141.     ici->next = shmnew; shmid = shmnew;
  142.     ici = (struct maillon *) shmat(shmid,0,SHM_SHARE_MMU);
  143.     if (ici==0) { perror("shmat"); exit(2); }
  144.     ici->next = shmid;
  145.     ici->debut = ici->fin = 0;
  146.     ici->fin++;
  147.   }
  148.   if (semop(semid, op_unlock, 1) < 0) { perror("semop"); exit(1); }
  149.   return 0;
  150. }
  151. int defile()
  152. {
  153.   puts("Defile");
  154.   if (semop(semid, op_lock, 2) < 0) { perror("semop"); exit(1); }
  155.   if (ici->debut == ici->fin) {
  156.     if (semop(semid, op_unlock, 1) < 0) { perror("semop"); exit(1); }
  157.     return 1;
  158.   }
  159.   ici->debut++;
  160.   if (ici->debut == TAILLE) {
  161.     int next = ici->next;
  162.     puts("Destruction d'un maillon");
  163.     shmdt((void*)ici);
  164.     if (shmctl(shmid,IPC_RMID,0)) { perror("shmctl"); }
  165.     shmid = next;
  166.     ici = (struct maillon *) shmat(shmid,0,SHM_SHARE_MMU);
  167.     if (ici==0) { perror("shmat"); exit(2); }
  168.   }
  169.   if (semop(semid, op_unlock, 1) < 0) { perror("semop"); exit(1); }
  170.   return 0;
  171. }
复制代码

请斑竹们体谅一下。。:rolleyes: 有简单点的例子吗??:confused: :confused:
 楼主| 发表于 2004-2-10 21:24:35 | 显示全部楼层

  1. #include <stdio.h>
  2. #include <unistd.h>
  3. #include <sys/shm.h>
  4. #include <sys/sem.h>
  5. #include <strings.h>
  6. #include <pthread.h>
  7. #include "sem.h"
  8. #include "pc.h"

  9. static int yin_shmid;
  10. static int yin_filled, yin_empty, yin_mutex;
  11. static int yang_shmid;
  12. static int yang_filled, yang_empty, yang_mutex;
  13. static char *yin_shmem_ptr;
  14. static char *yang_shmem_ptr;

  15. /*
  16. *   Remove shared memory IDs and semaphores.
  17. *   Ignore errors since maybe not all exist.
  18. */
  19. static void yin_cleanup()
  20. {
  21.         (void) shmdt(yin_shmem_ptr);
  22.         (void) shmdt(yang_shmem_ptr);

  23.         (void) shmctl(yin_shmid, IPC_RMID, NULL);
  24.         (void) shmctl(yang_shmid, IPC_RMID, NULL);
  25.         (void) semctl(yin_filled, 0, IPC_RMID);
  26.         (void) semctl(yin_empty, 0, IPC_RMID);
  27.         (void) semctl(yin_mutex, 0, IPC_RMID);
  28.         (void) semctl(yang_filled, 0, IPC_RMID);
  29.         (void) semctl(yang_empty, 0, IPC_RMID);
  30.         (void) semctl(yang_mutex, 0, IPC_RMID);

  31.                                                                                                 
  32.         exit(0);
  33. }
  34.                                                                                                 
  35. static void yin_init()
  36. {
  37. /* create shared memory segments */
  38.         if ((yin_shmid = shmget(IPC_PRIVATE, SHMSUS, 0600)) < 0) {
  39.                 perror("1st shmget"); yin_cleanup();
  40.         }
  41.         if ((yang_shmid = shmget(IPC_PRIVATE, SHMSUS, 0600)) < 0) {
  42.                 perror("2nd shmget"); yin_cleanup();
  43.         }
  44. /* attach to shared memory segments */
  45.         if ((int)(yin_shmem_ptr = (char *) shmat(yin_shmid, (void *)0, SHM_SHATTR)) < 0) {
  46.                 perror("1st shmat"); yin_cleanup();
  47.         }
  48.         if ((int)(yang_shmem_ptr = (char *) shmat(yang_shmid, (void *)0, SHM_SHATTR)) < 0) {
  49.                 perror("2nd shmat"); yin_cleanup();
  50.         }
  51.                                                                                                 
  52. /* create semaphores */
  53.         if ((yin_filled = semget(IPC_PRIVATE, 1, 0600)) < 0) {
  54.                 perror("yin_filled semget"); yin_cleanup();
  55.         }
  56.         Init(yin_filled, 0);
  57.         if ((yin_empty = semget(IPC_PRIVATE, 1, 0600)) < 0) {
  58.                 perror("yin_empty semget"); yin_cleanup();
  59.         }
  60.         Init(yin_empty, 1);
  61.         if ((yin_mutex = semget(IPC_PRIVATE, 1, 0600)) < 0) {
  62.                 perror("yin_mutex semget"); yin_cleanup();
  63.         }
  64.         Init(yin_mutex, 1);
  65.         if ((yang_filled = semget(IPC_PRIVATE, 1, 0600)) < 0) {
  66.                 perror("yang_filled semget"); yin_cleanup();
  67.         }
  68.         Init(yang_filled, 0);
  69.         if ((yang_empty = semget(IPC_PRIVATE, 1, 0600)) < 0) {
  70.                 perror("yang_empty semget"); yin_cleanup();
  71.         }
  72.         Init(yang_empty, 1);
  73.         if ((yang_mutex = semget(IPC_PRIVATE, 1, 0600)) < 0) {
  74.                 perror("yang_mutex semget"); yin_cleanup();
  75.         }
  76.         Init(yang_mutex, 1);
  77.                                                                                                 
  78.         return;
  79. }
  80.                                                                                                 
  81. int main()  /*                  main()                    */
  82. {
  83.         args_t produce_args;
  84.         args_t consume_args;
  85.         pthread_t second_thread;
  86.                                                                                                 
  87.         yin_init();
  88.                                                                                                 
  89. /* start consumer thread to read from yang */
  90.         consume_args.filled_sem = yang_filled;
  91.         consume_args.empty_sem = yang_empty;
  92.         consume_args.mutex_sem = yang_mutex;
  93.         consume_args.ptr = yang_shmem_ptr;
  94.         consume_args.cleanup_func = yin_cleanup;
  95.         if (pthread_create(&second_thread,
  96.                            NULL,
  97.                            Consume,
  98.                            (void *)&consume_args) != 0) {
  99.                 perror("pthread_create"); yin_cleanup();
  100.         }
  101. /* print shmid & semid only AFTER all initialization has succeeded */
  102.         printf("You will have to type this stuff into yang ...\n");
  103.         printf("Yin writes into shared memory ID %d\n", yin_shmid);
  104.         printf("\t Filled semaphore number: %d\n", yin_filled);
  105.         printf("\t Empty semaphore number: %d\n", yin_empty);
  106.         printf("\t Mutex semaphore number: %d\n", yin_mutex);
  107.         printf("Yang writes into shared memory ID %d\n", yang_shmid);
  108.         printf("\t Filled semaphore number: %d\n", yang_filled);
  109.         printf("\t Empty semaphore number: %d\n", yang_empty);
  110.         printf("\t Mutex semaphore number: %d\n", yang_mutex);
  111.                                                                                                 
  112. /* this thread starts produce loop */
  113.         produce_args.filled_sem = yin_filled;
  114.         produce_args.empty_sem = yin_empty;
  115.         produce_args.mutex_sem = yin_mutex;
  116.         produce_args.ptr = yin_shmem_ptr;
  117.         (void) Produce(&produce_args);
  118.                                                                                                 
  119. /* delete resources */
  120.         yin_cleanup();          /* never returns */
  121.         return(0);
  122. }
复制代码
 楼主| 发表于 2004-2-10 21:27:59 | 显示全部楼层

  1. /* $Header: p3.c,v 1.3 97/11/26 15:32:54 cs096403 Exp $ */
  2. /*
  3. * P3 BY Jeff Anderson, CSCI 325-01, Due: 11/26/97
  4. * PROGRAM ID:  p3.c / Conway's problem (Concurrent version using semaphores)
  5. * AUTHOR:  Jeff Anderson
  6. * INSTALLATION:  MIDDLE TENNESSEE STATE UNIVERSITY
  7. *
  8. * REMARKS:  This program reads 10-character blocks (from standard input)
  9. * and writes them as 24-character lines (to standard output) with the
  10. * following changes:
  11. *     - After every block an extra blank is inserted.
  12. *     - Every adjacent pair of asterisks is replaced by
  13. *       an exclamation point.  Asterisks are considered
  14. *       adjacent only if they are in the same block.
  15. * The newline character is not considered as a delimiter of an input block
  16. * and is ignored in input.  (However, the newline character is used as a
  17. * sentinel value between the child processes to denote the end of the
  18. * input stream.)
  19. *
  20. * INVOCATION:  This program is invoked on the command-line with two
  21. * arguments, the first is the size (in characters) of the buffer used
  22. * between the "readinput" and "squash" processes.  The second is the
  23. * size (in characters) of the buffer used between the "squash" and
  24. * "printoutput" processes.  Since this program runs as a filter, an
  25. * input file will usually be redirected into it.
  26. * For example,         % p3 5 9  <  data.file
  27. */
  28. #include <stdio.h>
  29. #include <stdlib.h>
  30. #include <signal.h>
  31. #include <unistd.h>
  32. #include <sys/wait.h>
  33. #include <sys/ipc.h>
  34. #include <sys/sem.h>
  35. #include <sys/shm.h>
  36.                                                                                                 
  37. #include "IPC.h"
  38. #include "p3.h"
  39.                                                                                                 
  40.                                                                                                 
  41. /* --- Global Variables, shared by main() and CleanupIPC() ---------------- */
  42. int     pid_readinput;     /* readinput process id                          */
  43. int     pid_squash;        /* squash process id                             */
  44. int     pid_printoutput;   /* printoutput process id                        */
  45.                                                                                                 
  46.                                                                                                 
  47.                                                                                                 
  48. /* --- Functions ---------------------------------------------------------- */
  49. void
  50. CleanupIPC(int sig) {
  51.         sem[NR]!=-1    ? semctl(sem[NR], 0,  IPC_RMID, 0) : 0;
  52.         sem[ER]!=-1    ? semctl(sem[ER], 0,  IPC_RMID, 0) : 0;
  53.         sem[NS]!=-1    ? semctl(sem[NS], 0,  IPC_RMID, 0) : 0;
  54.         sem[ES]!=-1    ? semctl(sem[ES], 0,  IPC_RMID, 0) : 0;
  55.         shm[RB]!=-1    ? shmctl(shm[RB],     IPC_RMID, 0) : 0;
  56.         shm[SB]!=-1    ? shmctl(shm[SB],     IPC_RMID, 0) : 0;
  57.         if (sig==0)
  58.                 return;
  59.                                                                                                 
  60.         else {
  61.                 (void) fprintf(stderr,
  62.                   "Error: p3 main() received signal %d\n", sig);
  63.                                                                                                 
  64.                 /* Explicitly signal children to die. */
  65.                 kill(pid_readinput, SIGKILL);
  66.                 kill(pid_squash, SIGKILL);
  67.                 kill(pid_printoutput, SIGKILL);
  68.                                                                                                 
  69.                 exit(FAILURE);
  70.         }
  71. }
  72. int
  73. main(int argc, char * argv[]) {
  74.                                                                                                 
  75.         int     read_buffer_capacity;    /* Capacity of Read Buffer       */
  76.         int     squash_buffer_capacity;  /* Capacity of Squash Buffer     */
  77.         char *  readinput_args[7];       /* readinput's argument vector   */
  78.         char *  squash_args[10];         /* squash's argument vector      */
  79.         char *  printoutput_args[7];     /* printoutput's argument vector */
  80.         int     sig;                     /* Signal number                 */
  81.         int     return_status, return_code;
  82.                                                                                                 
  83.                                                                                                 
  84.         /* Process command-line arguments. */
  85.         if (argc != 3) {
  86.                 ERROR("Missing command-line argument(s) to p3");
  87.                 exit(FAILURE);
  88.         }
  89.                                                                                                 
  90.         else {
  91.                 read_buffer_capacity   = atoi(argv[1]);
  92.                 squash_buffer_capacity = atoi(argv[2]);
  93.         }
  94.         /* Cause all signals to be caught by the "CleanupIPC" routine.
  95.          * The specific number of signals is somewhat system dependent;
  96.          * the top value (NSIG from signal.h) may need adjustment.
  97.          * NOTE: this implementation assumes that "Reliable Signal"
  98.          * semantics are implemented with signal().  If this isn't true,
  99.          * the sigaction() routine will need to be used.  See Stevens,
  100.          * Chapter 10 (especially pp. 296-299) for more information.
  101.         */
  102.         for (sig=1; sig < NSIG; sig++) {
  103.                                                                                                 
  104.                 switch(sig) {
  105.                 /* Don't try to catch these signals    */
  106.                 case SIGKILL: case SIGSTOP: case SIGCHLD:
  107.                         break;
  108.                                                                                                 
  109.                 default:
  110.                         if ( signal(sig, CleanupIPC)==SIG_ERR) {
  111.                                 (void) fprintf(stderr,
  112.                                   "Error: unable to catch signal %d", sig);
  113.                         }
  114.                         break;
  115.                 }
  116.         }
  117.         /* Set-up and initialize semaphores. */
  118.         sem[NR] = SemaphoreInit(0);
  119.         sem[ER] = SemaphoreInit(read_buffer_capacity);
  120.         sem[NS] = SemaphoreInit(0);
  121.         sem[ES] = SemaphoreInit(squash_buffer_capacity);
  122.                                                                                                 
  123.                                                                                                 
  124.         /* Set-up shared memory. */
  125.         shm[RB] = shmget(IPC_PRIVATE, read_buffer_capacity,   0600);
  126.         shm[SB] = shmget(IPC_PRIVATE, squash_buffer_capacity, 0600);
  127.                                                                                                 
  128.                                                                                                 
  129.         /* --- Invoke the "readinput" routine --- */
  130.         /*
  131.          * Set up argument list for invocation of the child process.
  132.          * Note that the following assignments merely assign to the
  133.          * args array the addresses where the argument values will be
  134.          * found and NOT the actual argument values themselves.
  135.         */
  136.         readinput_args[0] = "readinput";   /* Name of child executable image. */
  137.         readinput_args[1] = semstr[NR];
  138.         readinput_args[2] = semstr[ER];
  139.         readinput_args[3] = argv[1];       /* Read buffer capacity. */
  140.         readinput_args[4] = shmstr[RB];
  141.         readinput_args[5] = shmstr[SB];
  142.         readinput_args[6] = NULL;
  143.         sprintf(semstr[NR], "%d", sem[NR]);
  144.         sprintf(semstr[ER], "%d", sem[ER]);
  145.         sprintf(shmstr[RB], "%d", shm[RB]);
  146.         sprintf(shmstr[SB], "%d", shm[SB]);
  147.                                                                                                 
  148.         if ( (pid_readinput = fork()) < 0) {
  149.                                                                                                 
  150.                 OS_ERROR("Can't fork to run readinput.");
  151.                 exit(errno);
  152.         }
  153.                                                                                                 
  154.         else {
  155.                                                                                                 
  156.                 if (pid_readinput == 0) {   /* Child process:  run readinput. */
  157.                                                                                                 
  158.                         execvp("readinput",readinput_args);
  159.                         OS_ERROR("Invocation of readinput failed.");
  160.                         _exit( FAILURE );
  161.                 }
  162.         }
  163.         /* From this point on, we are running concurrently with readinput. */
  164.                                                                                                 
  165.                                                                                                 
  166.         /* --- Invoke the "squash" routine --- */
  167.         /*
  168.          * Set up argument list for invocation of the child process.
  169.          * Note that the following assignments merely assign to the
  170.          * args array the addresses where the argument values will be
  171.          * found and NOT the actual argument values themselves.
  172.         */
  173.         squash_args[0] = "squash";         /* Name of child executable image. */
  174.         squash_args[1] = semstr[NR];
  175.         squash_args[2] = semstr[ER];
  176.         squash_args[3] = argv[1];          /* Read buffer capacity. */
  177.         squash_args[4] = semstr[NS];
  178.         squash_args[5] = semstr[ES];
  179.         squash_args[6] = argv[2];          /* Squash bufffer capacity. */
  180.         squash_args[7] = shmstr[RB];
  181.         squash_args[8] = shmstr[SB];
  182.         squash_args[9] = NULL;
  183.                                                                                                 
  184.         sprintf(semstr[NR], "%d", sem[NR]);
  185.         sprintf(semstr[ER], "%d", sem[ER]);
  186.         sprintf(semstr[NS], "%d", sem[NS]);
  187.         sprintf(semstr[ES], "%d", sem[ES]);
  188.         sprintf(shmstr[RB], "%d", shm[RB]);
  189.         sprintf(shmstr[SB], "%d", shm[SB]);
  190.         if ( (pid_squash = fork()) < 0) {
  191.                                                                                                 
  192.                 OS_ERROR("Can't fork to run squash.");
  193.                 exit(errno);
  194.         }
  195.         else {
  196.                                                                                                 
  197.                 if (pid_squash == 0) {   /* Child process:  run squash. */
  198.                                                                                                 
  199.                         execvp("squash",squash_args);
  200.                         OS_ERROR("Invocation of squash failed.");
  201.                         _exit( FAILURE );
  202.                 }
  203.         }
  204.         /* From this point on, we are running concurrently with squash. */
  205.                                                                                                 
  206.                                                                                                 
  207.                                                                                                 
  208.         /* --- Invoke the "printoutput" routine --- */
  209.         /*
  210.          * Set up argument list for invocation of the child process.
  211.          * Note that the following assignments merely assign to the
  212.          * args array the addresses where the argument values will be
  213.          * found and NOT the actual argument values themselves.
  214.         */
  215.         printoutput_args[0] = "printoutput";   /* Name of child executable image. */
  216.         printoutput_args[1] = semstr[NS];
  217.         printoutput_args[2] = semstr[ES];
  218.         printoutput_args[3] = argv[2];         /* Squash buffer capacity. */
  219.         printoutput_args[4] = shmstr[RB];
  220.         printoutput_args[5] = shmstr[SB];
  221.         printoutput_args[6] = NULL;
  222.                                                                                                 
  223.         sprintf(semstr[NR], "%d", sem[NS]);
  224.         sprintf(semstr[ER], "%d", sem[ES]);
  225.         sprintf(shmstr[RB], "%d", shm[RB]);
  226.         sprintf(shmstr[SB], "%d", shm[SB]);
  227.                                                                                                 
  228.         if ( (pid_printoutput = fork()) < 0) {
  229.                                                                                                 
  230.                 OS_ERROR("Can't fork to run printoutput.");
  231.                 exit(errno);
  232.         }
  233.                                                                                                 
  234.         else {
  235.                                                                                                 
  236.                 if (pid_printoutput == 0) {   /* Child process:  run printoutput. */
  237.                                                                                                 
  238.                         execvp("printoutput",printoutput_args);
  239.                         OS_ERROR("Invocation of printoutput failed.");
  240.                         _exit( FAILURE );
  241.                 }
  242.         }
  243.         /* From this point on, we are running concurrently with printoutput. */
  244.         /* Finalizations */
  245.                                                                                                 
  246.         /* Wait until readinput finished. */
  247.         waitpid(pid_readinput, &return_status, 0);
  248.         return_code = WIFEXITED(return_status);
  249.                                                                                                 
  250.         /* Wait until squash finished. */
  251.         waitpid(pid_squash, &return_status, 0);
  252.         return_code = WIFEXITED(return_status);
  253.                                                                                                 
  254.         /* Wait until printoutput finished. */
  255.         waitpid(pid_printoutput, &return_status, 0);
  256.         return_code = WIFEXITED(return_status);
  257.                                                                                                 
  258.         CleanupIPC( 0 );
  259.                                                                                                 
  260.         exit(SUCCESS);
  261. }
复制代码
发表于 2004-2-11 19:59:33 | 显示全部楼层
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表