Linux进程间通信——管道通信_linux管道通信实验(1)

最全的Linux教程,Linux从入门到精通

======================

  1. linux从入门到精通(第2版)

  2. Linux系统移植

  3. Linux驱动开发入门与实战

  4. LINUX 系统移植 第2版

  5. Linux开源网络全栈详解 从DPDK到OpenFlow

华为18级工程师呕心沥血撰写3000页Linux学习笔记教程

第一份《Linux从入门到精通》466页

====================

内容简介

====

本书是获得了很多读者好评的Linux经典畅销书**《Linux从入门到精通》的第2版**。本书第1版出版后曾经多次印刷,并被51CTO读书频道评为“最受读者喜爱的原创IT技术图书奖”。本书第﹖版以最新的Ubuntu 12.04为版本,循序渐进地向读者介绍了Linux 的基础应用、系统管理、网络应用、娱乐和办公、程序开发、服务器配置、系统安全等。本书附带1张光盘,内容为本书配套多媒体教学视频。另外,本书还为读者提供了大量的Linux学习资料和Ubuntu安装镜像文件,供读者免费下载。

华为18级工程师呕心沥血撰写3000页Linux学习笔记教程

本书适合广大Linux初中级用户、开源软件爱好者和大专院校的学生阅读,同时也非常适合准备从事Linux平台开发的各类人员。

需要《Linux入门到精通》、《linux系统移植》、《Linux驱动开发入门实战》、《Linux开源网络全栈》电子书籍及教程的工程师朋友们劳烦您转发+评论

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以点击这里获取!

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#define MAXSIZE 100

int main()
{
    int fd[2], pid, line;
    char message[MAXSIZE];
    /\*创建管道\*/
    if(pipe(fd) == -1)
    {
	perror("create pipe failed!");
	return 1;
    }
    /\*创建新进程\*/
    else if((pid = vfork()) < 0)
    {
	perror("not create a new process!");
	return 1;
    }
    /\*子进程\*/
    else if(pid == 0)
    {
	close(fd[0]);
	printf("child process SEND message!\n");
	write(fd[1], "Hello Linux!",12); /\*向文件中写入数据\*/ 
    }
    else
    {
	close(fd[1]);
	printf("parent process RECEIVE message is:\n");
	line = read(fd[0], message, MAXSIZE); /\*读取消息,返回消息长度\*/
	write(STDOUT_FILENO,message,line); /\*将消息写入终端\*/
	printf("\n");
	wait(NULL);
	\_exit(0);
    }
    return 0;
}


结果:
在这里插入图片描述
管道特点:

  1. 只能用于具有共同祖先的进程(具有亲缘关系的进程)之间进行通信;通常,一个管道由一个进程创建,然后该进程调用fork(),此后父子进程之间就可以应用该管道。
  2. 一般而言,进程退出,管道释放,所以管道的生命周期跟随进程。
  3. 一般而言,内核会对管道操作进行同步与互斥
  4. 管道是半双工的,数据只能向一个方向流动;需要双方通信时,需要建立起两个管道。
    在这里插入图片描述

3. 命名管道

以上介绍的管道通信的方法有很多限制。受限制之一就是两个进程必须是相关联的进程。若是没有关系的进程间通信就要用命名管道。命名管道通常被称为FIFO。它作为特殊的设备文件存在于文件系统中。因此,在进程中可以使用open()和close()函数打开和关闭命名管道。

3.1 创建一个命名管道
· 命名管道可以从命令行上创建,命令行方法是使用下面这个命令:

$ mkfifo filename

· 也可以从程序里创建,相关函数:

#include <sys/tyoes.h>
#include <sys/stat.h>
int mkfifo(const char\* pathname, mode_t mode);

该函数的参数pathname是一个文件的路径名,是创建的一个命名管道的文件名;参数mode是指文件的权限,文件权限取决于(mode&~umask)的值。
使用mkfifo()函数创建的命名管道文件与前面介绍的管道通信相似,只是它们创建方式不同。访问命名管道文件与访问文件系统中的其他文件一样,都是需要首先打开文件,然后对文件进行读写数据。如果在命名管道文件中读取数据时,并没有其他进程向命名管道文件中写入数据,则会出现进程阻塞状态;如果在写入数据的同时,没有进程从命名管道中读取数据,也会出现进程阻塞状态。
程序如下:

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#define FIFO "/root/process/hello"

int main()
{
    int fd;
    int pid;
    char r_msg[BUFSIZ];
    if((pid = mkfifo(FIFO,0777))==-1) /\*创建命名管道\*/
    {
	perror("create fifo channel failed!");
	return 1;
    }
    else
    printf("create success!\n");
    fd = open(FIFO, O_RDWR);  /\*打开命名管道\*/
    if(fd == -1)
    {
	perror("cannot open the FIFO");
	return 1;
    }
    if(write(fd,"hello world", 12) == -1)  /\*写入消息\*/
    {
	perror("write data error!");
	return 1;
    }
    else
    printf("write data success!\n");
    if(read(fd, r_msg, BUFSIZ) == -1)  /\*读取消息\*/
    {
	perror("read error!");
	return 1;
    }
    else
    printf("the receive data is: %s\n",r_msg);
    close(fd);   /\*关闭文件\*/
    return 0;
}


在这里插入图片描述

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以点击这里获取!

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值