2进程如何相互交谈,而不管()? [英] How can 2 processes talk to each other without pipe()?

查看:156
本文介绍了2进程如何相互交谈,而不管()?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有鉴于此code:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>

#define BUF_SIZE 256

int main()
{
    int fd1[2];
    int fd2[2];

    ssize_t numRead = -1;

    // remark : working under the assumption that the messages are of equal length

    const char* messageOne = "Hello world , I'm child number 1\n";
    const char* messageTwo = "Hello world , I'm child number 2\n";

    const unsigned int commLen = strlen(messageOne) + 1;

    char buf[BUF_SIZE];

    if (pipe(fd1) == -1)
    {
        printf("Error opening pipe 1!\n");
        exit(1);
    }

    if (pipe(fd2) == -1)
    {
        printf("Error opening pipe 2!\n");
        exit(1);
    }

    printf("Piped opened with success. Forking ...\n");

    // child 1
    switch (fork())
    {
        case -1:
            printf("Error forking child 1!\n");
            exit(1);

        case 0:
            printf("\nChild 1 executing...\n");
            /* close reading end of first pipe */
            if (close(fd1[0]) == -1)
            {
                printf("Error closing reading end of pipe 1.\n");
                _exit(1);
            }
            /* close writing end of second pipe */
            if (close(fd2[1]) == -1)
            {
                printf("Error closing writing end of pipe 2.\n");
                _exit(1);
            }

            /* write to pipe 1 */
            if (write(fd1[1], messageOne, commLen) != commLen)
            {
                printf("Error writing to pipe 1.\n");
                _exit(1);
            }

            if (close(fd1[1]) == -1)
            {
                printf("Error closing writing end of pipe 1.\n");
                _exit(1);
            }

            /* reding from pipe 2 */
            numRead = read(fd2[0], buf, commLen);
            if (numRead == -1)
            {
                printf("Error reading from pipe 2.\n");
                _exit(1);
            }

            if (close(fd2[0]) == -1)
            {
                printf("Error closing reding end of pipe 2.\n");
                _exit(1);
            }

            printf("Message received child ONE: %s", buf);
            printf("Exiting child 1...\n");
            _exit(0);
            break;

        default:
            break;
    }

    // child 2
    switch (fork())
    {
        case -1:
            printf("Error forking child 2!\n");
            exit(1);
        case 0:
            printf("\nChild 2 executing...\n");
            /* close reading end of second pipe */
            if (close(fd2[0]) == -1)
            {
                printf("Error closing reading end of pipe 2.\n");
                _exit(1);
            }
            /* close writing end of first pipe */
            if (close(fd1[1]) == -1)
            {
                printf("Error closing writing end of pipe 1.\n");
                _exit(1);
            }

            /* read from the first pipe */
            if (read(fd1[0], buf, commLen) == -1)
            {
                printf("Error reading from pipe 1.\n");
                _exit(EXIT_FAILURE);
            }

            if (close(fd1[0]) == -1)
            {
                printf("Error closing reading end of pipe 1.\n");
                _exit(EXIT_FAILURE);
            }

            /* write to the second pipe */
            if (write(fd2[1], messageTwo, commLen) != commLen)
            {
                printf("Error writing to the pipe.");
                _exit(EXIT_FAILURE);
            }

            if (close(fd2[1]) == -1)
            {
                printf("Error closing writing end of pipe 2.");
                _exit(EXIT_FAILURE);
            }

            printf("Message received child TWO: %s", buf);
            printf("Exiting child 2...\n");
            _exit(EXIT_SUCCESS);
            break;

        default:
            break;
    }

    printf("Parent closing pipes.\n");

    if (close(fd1[0]) == -1)
    {
        printf("Error closing reading end of the pipe.\n");
        exit(EXIT_FAILURE);
    }

    if (close(fd2[1]) == -1)
    {
        printf("Error closing writing end of the pipe.\n");
        exit(EXIT_FAILURE);
    }

    if (close(fd2[0]) == -1)
    {
        printf("Error closing reading end of the pipe.\n");
        exit(EXIT_FAILURE);
    }

    if (close(fd1[1]) == -1)
    {
        printf("Error closing writing end of the pipe.\n");
        exit(EXIT_FAILURE);
    }

    printf("Parent waiting for children completion...\n");
    if (wait(NULL) == -1)
    {
        printf("Error waiting.\n");
        exit(EXIT_FAILURE);
    }

    if (wait(NULL) == -1)
    {
        printf("Error waiting.\n");
        exit(EXIT_FAILURE);
    }

    printf("Parent finishing.\n");
    exit(EXIT_SUCCESS);
}

这是使用管道两个进程之间简单的谈话()

输出是:

Piped opened with success. Forking ...
Parent closing pipes.
Parent waiting for children completion...

Child 2 executing...

Child 1 executing...
Message received child TWO: Hello world , I'm child number 1
Exiting child 2...
Message received child ONE: Hello world , I'm child number 2
Exiting child 1...
Parent finishing.

正如你可以从上面看到,这两个孩子是讲一个具有另一种使用管道 。但我想这样做没有他们的管道,这可能吗?如果是这样,请解释一下我如何不想使用管道(),我确实想模拟 管()

As you can see from the above , the two children are speaking one with the other using fork and pipe . But I want to do this without piping them , is it possible ? if so please explain how , I don't want to use the pipe() , what I do want to simulate pipe() .

感谢

推荐答案

我已经修改程序,以显示System V共享内存的例子。避免竞争
条件信号(POSIX信号命名)也被使用。我已经写了一些意见了。 PL。看看这个例子帮助。
各个功能手册页面可以被称为了解更多的功能。编译标志应该是-lpthread。要生成密钥(指一个独特的共享内存段)现有文件(我把它命名为anyfile)应在当前目录下是可用的,因为我已经使用ftok功能。 PL。添加适当的错误装卸也一样,通过检查
的函数的返回值。

I have modified your program, to show an example of System V shared memory . To avoid race conditions semaphore (POSIX named semaphore) is also used. I have written some comments too. Pl. see if this example helps. Manual page of the individual functions can be referred to learn more about the functions. Compilation flag should be -lpthread. To generate the key (to refer an unique shared memory segment)an existing file (I have named it "anyfile") should be available in the current directory, since I have used ftok function. Pl. add proper error handlings too, by checking the return value of the functions.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/shm.h>
#include <semaphore.h>

#define BUF_SIZE 256
int main()
{
    key_t key;
    char *virtualaddr;
    sem_t *get, *put;
    ssize_t numRead = -1;
    int shmid;

   const char* messageOne = "Hello world , I'm child number 1\n";
   const char* messageTwo = "Hello world , I'm child number 2\n";

   const unsigned int commLen = strlen(messageOne) + 1;
   char buf[BUF_SIZE];

   key = ftok("anyfile",'R');

  shmid = shmget(key,1024,0644|IPC_CREAT);
  if (0 > shmid)
  {
    perror("Shared Mem creation error\n");
    exit(1);

  }
//Attaching  the shared mem to my address space(available across fork)
 virtualaddr = shmat(shmid, (void*)0, 0);
  /*Create two POSIX Named Semaphores, get and put and initialising with 0*/
 get = sem_open("/get", O_CREAT|O_RDWR, 0644, 0);

 put = sem_open("/put", O_CREAT|O_RDWR, 0644, 0);

 // child 1
switch (fork())
{
    case -1:
        printf("Error forking child 1!\n");
        exit(1);
    case 0:
        printf("\nChild 1 executing...\n");
    //Referring the semaphores..
    get = sem_open ("/get", O_RDWR);
    put = sem_open ("/put", O_RDWR);

    //Child 1 writing in shared mem
        strcpy (virtualaddr, messageOne);
    //Child 1 signalling that now child 2 can write
        sem_post (get);
    //Child1 waiting for Child2 to write..
    sem_wait (put);
    //Child 1 reading from shared mem
    strcpy (buf, virtualaddr);          
    printf("Message received child ONE: %s", buf);
        printf("Exiting child 1...\n");
        _exit(0);
        break;
 default:
        break;
}
// child 2
switch (fork())
{
    case -1:
        printf("Error forking child 2!\n");
        exit(1);
    case 0:
        printf("\nChild 2 executing...\n");
    //Referring the semaphores..
    get = sem_open ("/get", O_RDWR);
    put = sem_open ("/put", O_RDWR);

    //Waiting Till Child 1 has written.
        sem_wait (get);
        //Now child 2 can read from shared memory
    strcpy (buf, virtualaddr);
    //Child 2 writing in shared mem
    strcpy (virtualaddr,messageTwo );
    //Signalling that now Child 1 can read.
    sem_post (put);                            
        printf("Exiting child 2...\n");
    printf("Message received child TWO: %s", buf);
        _exit(EXIT_SUCCESS);
        break;

    default:
        break;
}
printf("Parent waiting for children completion...\n");

if (wait(NULL) == -1)
{
    printf("Error waiting.\n");
    exit(EXIT_FAILURE);
}

if (wait(NULL) == -1)
{
    printf("Error waiting.\n");
    exit(EXIT_FAILURE);
}

printf("Parent finishing.\n");
//Deleting semaphores..
sem_unlink ("/get");
sem_unlink ("/put");
//Deleting Shared Memory.
shmctl (shmid, IPC_RMID, NULL);
exit(EXIT_SUCCESS);

}

这篇关于2进程如何相互交谈,而不管()?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆