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

上学期接触了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系统是基于Linux系统的,所以有必要简单的介绍下Linux的跨进程通信,对大家后续了解Andr...
    Sophia_dd35阅读 809评论 0 4
  • 前言 管道是UNIX环境中历史最悠久的进程间通信方式,也是最简单的进程间通信方式,一般用来作为IPC的入门,最合适...
    GeekerLou阅读 1,219评论 0 6
  • 一.管道机制(pipe) 1.Linux的fork操作 在计算机领域中,尤其是Unix及类Unix系统操作系统中,...
    Geeks_Liu阅读 3,731评论 1 9
  • 操作系统概论 操作系统的概念 操作系统是指控制和管理计算机的软硬件资源,并合理的组织调度计算机的工作和资源的分配,...
    野狗子嗷嗷嗷阅读 12,113评论 3 34
  • 如果想享受一次高品质的旅游,千万不能跟旅游团。跟团旅游,一是赶路,走马观花。一大群人跟着导游,择几个景点讲解一番,...
    彩莲阅读 382评论 0 0