对于 sleep() 同步父进程和子进程之间的传输,我有什么选择?

What alternatives I have against sleep() to synchronize transfer between parent and child process?

我正面临同步问题,我试图解决的问题涉及将字符串从父级发送到子级、将其反转并将其发送回子级(使用共享内存)。

但是为了确保子进程正在等待父进程,我使用 sleep(3) 给父进程 3 秒来输入字符串,但是这限制了我的程序效率,我不这样做想要强制用户等待 3 秒。

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <sys/wait.h>  /* Needed for the wait function */
#include <unistd.h>    /* needed for the fork function */
#include <string.h>    /* needed for the strcat function */
#define SHMSIZE 27

int main() {
    int shmid;
    char *shm;

    if(fork() == 0) {
        sleep(3);
        shmid = shmget(29009, SHMSIZE, 0);
        shm = shmat(shmid, 0, 0);
        printf ("Child : Reading %s \n",shm) ;
        int len=strlen(shm);
        char rev[100],temp;

        int i = 0;
        int j = strlen(shm) - 2;

        while (i < j) {
            temp = shm[i];
            shm[i] = shm[j];
            shm[j] = temp;
            i++;
            j--;
        }
        shmdt(shm);

    }else {
        shmid = shmget(29009, SHMSIZE, 0666 | IPC_CREAT);
        shm = shmat(shmid, 0, 0);

        printf("Parent : Enter String \n ");
        char *s = (char *) shm;
        *s = '[=10=]';
        char a[100];
        fgets(a,100,stdin);
        strcat(s,a);
        printf ("Parent: sending %s \n",shm);
        sleep(3);
        printf("Parent: receiving %s" ,shm);
        shmdt(shm);

   }
   return 0;
}

问题:

  1. 如何以更好的方式实施,使程序更有效率?

我建议使用信号量,这不是您使用 'sleep' 的情况: http://man7.org/linux/man-pages/man7/sem_overview.7.html

您可以像本例中那样使用它们: http://www.csc.villanova.edu/~mdamian/threads/posixsem.html

你无法确定它不会超过 3 秒,所以睡眠是一个非常糟糕的选择。所以,它是这样的:

#include <stdio.h>

#include <semaphore.h>


int main(void)
{
sem_t *sem = mmap(0, sizeof(sem_t), PROT_READ|PROT_WRITE,
              MAP_SHARED|MAP_ANONYMOUS, -1, 0);

sem_init(sem, 1, 1);

if(fork() == 0) {
    printf("Child: Waiting to acquire semaphore\n");
    sem_wait(sem);
    printf("Child acquires lock\n");
    /* do whatever you want then relese*/
    sem_post(sem);
} else {
    printf("Parent: Waiting to acquire semaphore\n");
    sem_wait(sem);
    printf("Parent acquires lock\n");
    /* do whatever you want then relese*/
    sem_post(sem);
}

sem_destroy(sem);
return 0;
}

哦,如果你想让它 parent 后面跟着 child 总是(或者相反),你可以使用两个信号量,并相应地初始化它们(用 1 和 0,或 0 和 1).

    sem_wait(sem1);
    printf("Parent acquires lock\n");
    /* do whatever you want then relese*/
    sem_post(sem2);

/* Other things will be happening here */

    sem_wait(sem2);
    printf("Child acquires lock\n");
    /* do whatever you want then relese*/
    sem_post(sem1);

编辑

如果不用共享内存,最好用sockets通信

感谢神奇的 Whosebug 社区来拯救我!我已经解决了使用信号量解决的问题!我正在分享我的最终代码,因此它可以用于任何遇到像我这样的情况的人!

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <sys/wait.h>  /* Needed for the wait function */
#include <unistd.h>    /* needed for the fork function */
#include <string.h>    /* needed for the strcat function */
#include <semaphore.h>
#include <sys/mman.h>
#include<fcntl.h>
#include<stdlib.h>
#define SHMSIZE 27
typedef struct {
    sem_t one;
    sem_t two;
} SemPair;
int main() {


 int shm = shm_open("/test", O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
    ftruncate(shm, sizeof(sem_t));
    SemPair *sem = mmap(NULL, sizeof(sem_t), PROT_READ | PROT_WRITE, MAP_SHARED, shm, 0);

 sem_init(&(sem->one), 1, 0);
 sem_init(&(sem->two), 1, 0);

   int shmid;
   char *shmz;

   if(fork() == 0) {
      sem_wait(&(sem->one));
      shmid = shmget(29009, SHMSIZE, 0);
      shmz = shmat(shmid, 0, 0);
      printf ("Child : Reading %s \n",shmz) ;
      int len=strlen(shmz);
      char rev[100],temp;
 int  i = 0;
   int   j = strlen(shmz) - 2;
   while (i < j) {
      temp = shmz[i];
      shmz[i] = shmz[j];
      shmz[j] = temp;
      i++;
      j--;
   }


    shmdt(shmz);
    sem_post(&(sem->two));
   }
   else {
      shmid = shmget(29009, SHMSIZE, 0666 | IPC_CREAT);
      shmz = shmat(shmid, 0, 0);

      printf("Parent : Enter String \n ");
      char *s = (char *) shmz;
      *s = '[=10=]';
      char a[100];
      fgets(a,100,stdin);
      strcat(s,a);
      printf ("Parent: sending %s \n",shmz);
      sem_post(&(sem->one));
      sem_wait(&(sem->two));
      printf("Parent: receiving %s" ,shmz);
      shmdt(shmz);

}
   return 0;
}