无名管道及用其实现父子进程间的通信

一.引言

 在同一台计算机中的进程相互通信的方式主要有:管道(pipe)、信号(Signal)、信号量(Semaphore)、消息队列(Message)、共享内存(shared memory),其中信号量、消息队列、共享内存被称为IPC机制。Posix   system v fork()   CreateProcess   CreateThread pthread_create()
不同机器之间的进程通讯可以使用套接字技术。SOCKET

1.管道(匿名管道)
管道是IPC机制中的最老形式,是进程直接进行数据交换得通道,并且所有UNIX系统都提供了此种通信机制,管道分为普通管道和命名管道,他们都是通过内核缓冲区按先进先出得方式进行数据传输,其普通管道的特点为:
半双工
只能在具有公共祖先的进程之间使用
单独构成一种独立的文件系统
没有名字
管道的缓冲区是有限的
管道说传送的数据是无格式的
写入管道的数据读完之后就从管道中消失
2.管道的创建与读写
(1)无名管道
创建管道:Int pipe(int fd[2]);
fd[0]读出数据
fd[1]写入数据
(2)命名管道
创建管道:int mkfifo(const char *pathname, mode_t mode);
一般文件的I/O操作函数都可以用于管道。
close(fd)
int read(fd, buffer, len)
int write(fd, buffer, len)
二.匿名管道代码演示
利用匿名管道实现剧本化的对话

/*用无名管道进行通信
 *采取剧本的方式
 *2017-3-6
 * */
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h>
#include<sys/wait.h>
#include<time.h>

#define MAX_MSG_SIZE 256

int main()
{
    char* parent_talk[] = {"hello", "what is the time?", "ok, bye", NULL};
    char* child_talk[] = {"hi", "time is ", "bye", NULL};

    int fd1[2];
    int fd2[2];
    int res = pipe(fd1);
    if(res == -1)
    {
        perror("pipe");
        exit(EXIT_FAILURE);
    }
    res = pipe(fd2);
    if(res == -1)
    {
        perror("pipe");
        exit(EXIT_FAILURE);
    }
    pid_t pid = fork();
    if(pid == 0)//child
    {
        close(fd1[1]);
        close(fd2[0]);

        char buf[MAX_MSG_SIZE];
        int i = 0;
        char *talk = child_talk[i];
        while(talk != NULL)
        {
            read(fd1[0], buf, MAX_MSG_SIZE);
            printf("parent say:>%s\n", buf);
            write(fd2[1], talk, strlen(talk)+1);
            i++;
            talk = child_talk[i];
        }
        close(fd1[0]);
        close(fd2[1]);
    }
    else if(pid > 0)//parent
    {
        close(fd1[0]);
        close(fd2[1]);

        char buf[MAX_MSG_SIZE];
        int i = 0;
        char *talk = parent_talk[i];
        while(talk != NULL)
        {
            write(fd1[1], talk, strlen(talk)+1);
            read(fd2[0], buf, MAX_MSG_SIZE);
            if(strcmp(buf, child_talk[1]) == 0)
            {
                time_t timep;
                struct tm *p;
                time(&timep);;
                strcat(buf, ctime(&timep));
            }
            printf("child :>%s\n", buf);
            i++;
            talk = parent_talk[i];
        }
        close(fd1[1]);
        close(fd2[0]);
        int stat;
        wait(&stat);
    }
    else
    {
        perror("fork");
        exit(EXIT_FAILURE);
    }
    return 0;
}

测试结果
这里写图片描述
利用匿名管道实现正常的对话

/*匿名管道通信
 *采取对话的形式
 * 2017-3-6
 * */
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/wait.h>
#include<string.h>

#define MAX_MSG_SIZE 256

int main()
{
    int fd1[2];
    int fd2[2];
    int res = pipe(fd1);
    if(res == -1)
    {
        perror("pipe");
        exit(EXIT_FAILURE);
    }
    res = pipe(fd2);
    if(res == -1)
    {
        perror("pipe");
        exit(EXIT_FAILURE);
    }
    pid_t pid;
    pid = fork();
    if(pid == 0)    //child process
    {
        char sendbuffer[MAX_MSG_SIZE] = {'\0'};
        char recbuffer[MAX_MSG_SIZE] = {'\0'};
        close(fd1[1]);
        close(fd2[0]);
        while(1)
        {
            read(fd1[0], recbuffer, MAX_MSG_SIZE);
            printf("parent(by child):>%s\n", recbuffer);
            printf("child say (by child):>");
            scanf("%s", &sendbuffer);
            if(strcmp(sendbuffer, "quit") == 0)
                break;
            write(fd2[1], sendbuffer, strlen(sendbuffer)+1);
        }
        close(fd1[0]);
        close(fd2[1]);
    }
    else if(pid > 0)//parent process
    {
        char sendbuffer[MAX_MSG_SIZE] = {'\0'};
        char recbuffer[MAX_MSG_SIZE] = {'\0'};
        close(fd1[0]);
        close(fd2[1]);
        while(1)
        {
            printf("parent say (by parent):>");
            scanf("%s", &sendbuffer);
            if(strcmp(sendbuffer, "quit") == 0)
                break;
            write(fd1[1], sendbuffer, strlen(sendbuffer)+1);
            read(fd2[0], recbuffer, MAX_MSG_SIZE);
            printf("child(by parent):>%s\n", recbuffer);
        }
        close(fd1[1]);
        close(fd2[0]);
        int stat;
        wait(&stat);
    }
    else
    {
        perror("fork child process");
        exit(EXIT_FAILURE);
    }
}

测试结果
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值