美文网首页
Linux进程通信实验(管道通信)

Linux进程通信实验(管道通信)

作者: 努力学产品的阿凡 | 来源:发表于2019-03-02 16:09 被阅读0次

上学期接触了linux系统,刚好操作系统课程的实验内容也都是要求在linux下完成,几个实验中个人认为对两个进程通信实验了解学习的比较好,所以这一篇和下一篇记录一下两个实验过程中的学习收获和实验成果。

这个实验需要先对管道以及fork()创建出的子父进程等知识有一个大致的了解,具体可以参看以下两篇博客:https://blog.csdn.net/rl529014/article/details/51464363
https://www.jianshu.com/p/430340c4a37a
尤其是有名管道和无名管道(本实验使用的是无名管道)有一定的了解。

实验要求:由父进程创建一个管道和三个子进程,实现子进程和父进程间的通信(三个子进程发送后父进程接收)并测试管道大小以及进程对管道的实际写入字节数。

#include<unistd.h>
#include<sys/types.h>
#include<errno.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX_DATA_LEN    256
#define DELAY_TIME      1

int main()
{
    pid_t pid1,pid2,pid3;
    int pipe_fd[2];
    int len,realen,pipeid;
    char buf[MAX_DATA_LEN],outpipe[MAX_DATA_LEN];
        pipeid=pipe(pipe_fd);
    if(pipeid<0) 
    {
        printf("pipe error\n");
        exit(1);
    }
        if((pid1=fork())==-1){
                printf("pid1 error!\n");
                exit(1);
        }
    if(pid1==0)  {  
        sleep(DELAY_TIME);
        printf("pid1 is:%d\n",getpid());
        close(pipe_fd[0]); 
        sprintf(outpipe,"I'm child1!\n");
        len=strlen(outpipe);
        realen=write(pipe_fd[1], outpipe, len);
        printf("child1 writes %d bytes\n",realen);
        exit(0);
    }
    if((pid2=fork())==-1){
                printf("pid2 error!\n");
                exit(1);
        }
        if(pid2==0)  {  
        sleep(DELAY_TIME);
        printf("pid2 is:%d\n",getpid());
        close(pipe_fd[0]); 
        sprintf(outpipe,"I'm child2!\n");
        len=strlen(outpipe);
        realen=write(pipe_fd[1], outpipe, len);
        printf("child2 writes %d bytes\n",realen);
        exit(0);
    }
        if((pid3=fork())==-1){
                printf("pid3 error!\n");
                exit(1);
        }
        if(pid3==0)  {  
        sleep(DELAY_TIME);
        printf("pid3 is:%d\n",getpid());
        close(pipe_fd[0]); 
        sprintf(outpipe,"I'm child3!\n");
        len=strlen(outpipe);
        realen=write(pipe_fd[1], outpipe, len);
        printf("child3 writes %d bytes\n",realen);
        exit(0);
    }
    else{
        sleep(DELAY_TIME*3); 
        pid1 = waitpid(pid1,NULL,WUNTRACED); 
                pid2 = waitpid(pid2,NULL,WUNTRACED);  
                pid3 = waitpid(pid3,NULL,WUNTRACED); 
        printf("father pid is:%d\n",getpid());
        close(pipe_fd[1]); 
        read(pipe_fd[0],buf,sizeof(buf));
        printf("children date is: \n%s\n",buf);
    }
        return 0;
}

由于fork()创建的几个进程之间运行的先后顺序无法确定,所以这个实验中存在同步互斥问题,父进程需要等待三个子进程运行完毕后再读出并打印管道中的数据。不过我没有用信号量,而是使用了waitpid()实现的。

测试管道容量的实现比较简单,设置了一个固定大小为1024的数据段,只需要把这一段重复写入管道,每写入一次都计数一次,写到管道满时即可通过写入次数来得知管道的大小了。

#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#define MAX_DATA_LEN    1024

void write_to_pipe(int pipe_fd[2]);

int main(void)
{
    int pipe_fd[2];
    pid_t pid;
    int ret = -1;
    pipe(pipe_fd);
    pid = fork();

    if(pid == 0) {
        write_to_pipe(pipe_fd);
    } 
    else {
        wait(NULL);
    }  
}

void write_to_pipe(int pipe_fd[2])
{
    int count, ret;
    char buf[MAX_DATA_LEN];
    close(pipe_fd[0]);
    memset(buf, '*', MAX_DATA_LEN);

    ret = write(pipe_fd[1], buf, sizeof(buf));
    count = 1;
    printf(" Pipe has: %d kb\n", count);
    while (1) {
        ret = write(pipe_fd[1], buf, sizeof(buf)); 
    if(ret == -1){
        printf("1\n");
        break;                              
    }
        count++;
        printf(" Pipe has: %d kb\n", count);
    }
}

实验心得:熟悉了管道通信的基础框架,对fork、vfork也有了更深入的了解。

相关文章

  • 零散的小知识记录(待补充和修改)

    Android跨进程通信:Binder,socket/管道/消息队列,共享内存; linux进程间通信:管道,Bi...

  • Linux进程间通信

    Linux进程间通信的概念 linux下进程间通信的几种主要手段简介: 管道(Pipe)及有名管道(named p...

  • Linux进程通信实验(管道通信)

    上学期接触了linux系统,刚好操作系统课程的实验内容也都是要求在linux下完成,几个实验中个人认为对两个进程通...

  • Linux进程基础行为(二)

    本节主要讲Linux进程间通信在Linux中,各个进程都共享内核空间,因此LInux进程通信中的管道,消息队列等都...

  • Linux系统编程:Inter-Process Communic

    一、IPC——进程间通信 Linux系统提供的进程间通信的手段: 消息传递类:信号 匿名管道 命名管道 socke...

  • Android 进程通信--Binder机制

    一、起源——为什么在Android中使用binder通信机制? linux中的进程通信 管道包含无名管道和有名管道...

  • LInux进程之间的通信-有名管道(FIFO)

    Linux进程间的通信-有名管道FIFO 管道的通信只能存在于具有亲缘关系的进程之间,比如fork出来的子进程与父...

  • 进程间的通信

    进程间的通信方式(IPC)有哪些,各有什么优缺点? Linux内核解析:进程间通信:管道 - 笨拙的菜鸟 - 博客...

  • Binder 原理整理

    linux进程间通信方式 1. 管道 管道的实质是一个内核缓冲区,管道的作用正如其名,需要通信的两个进程在管道的两...

  • Linux 进程间通信

    进程间通信 一 进程间通信 -- 管道 mkfifo test 创建管道文件 匿名管道和命名管道:匿名管道:匿名管...

网友评论

      本文标题:Linux进程通信实验(管道通信)

      本文链接:https://www.haomeiwen.com/subject/ziaeuqtx.html