C语言-Linux进程间通信方式

1、进程间通信方式概述

进程间通信方式有:
    管道(Pipo)和有名管道(FIFO):用于具有亲缘关系进行间通信,有名管道,允许无亲缘关系进程间的通信
    信号(Signal):比较复杂的通信方式,用于通知接收进程有某种事件发生
    消息队列:消息的连接表,包括Posix消息队列和System V消息队列
    信号量(Signal)/信号灯:主要被用作进程间或同一进程不同线程之间的同步手段
    共享内存:最有用的进程间通信方式,需要某种同步机制,互斥锁和信号量都可以
    套接字:用于不同机器之间的进程间通信

进程间通信的目的
    数据传输、共享数据、通知事件、资源共享、进程控制

2、管道通信

特点:
    半双工,数据只能一个方向流动,进行双方通信的时候要建立两个管道,用于父子间或兄弟进程间通信
    一个进程向管道中写的数据内容被管道另一端的进程读出
    写入的数据每次都添加在管道缓冲区的末尾,并且每次都是从缓冲区的头部读出数据
    一般的I/O函数都可以用于管道,如close、read、write等

读数据步骤:
    若写端不存在,则认为以及读到了数据的末尾,读函数返回读出的字节数为0
    若管道的写端存在,请求的字节数目大于PIPE_BUE(定义在include/linux/limits中),返回现有字节数,不大于的话,返回现有字节数或请求字节数
    在管道写端关闭后,写入的数据将一直存在,直到被读出为止

写端对读端的依赖性:
    在向进程中写入数据时,至少应该存在某一个进程,其中管道读端没有被关闭。否则就会出现管道断裂,进程收到SIGPIPE信号,默认动作为进程终止

2.1 创建无名管道

函数详解 

表头文件
    #include <unistd.h>
    
定义函数
    int pipe(int filedes[2]);
    
函数说明
    用于建立管道
    将文件描述符由参数filedes数组返回
    filedes[0] 为管道的读取端
    filedes[1] 为管道的写入端
    
返回值
    成功返回零,否则返回-1

综合案例 

#include <stdio.h>
#include <unistd.h>

int main(int argc,char *argv[])
{
	int filedes[2];
	char buffer[80];
	pipe(filedes);
	if(fork() > 0)
	{
		char s[] = "hello!\n";
		write(filedes[1],s,sizeof(s));
	}
	else
	{
		read(filedes[0],buffer,80);
		printf("father %s",buffer);
	}

	return 0;
}

运行结果

linux@ubuntu:~/test$ gcc pipe_dome.c -o pipe_dome
linux@ubuntu:~/test$ ./pipe_dome 
father hello!

2.2 创建有名管道

函数详解  

表头文件
    #include <sys/types.h>
    #include <sys/stat.h>
    
定义函数
    int mkfifo(const char* pathname,mode_t mode);
    
函数说明
    pathname: 建立特殊的FIFO文件,该文件必须不存在
    mode: 描述pahtname文件的权限
    当使用open()打开文件时,O_NONBLOCK旗标会有下列影响:
        当使用O_NONBLOCK旗标时,打开文件来读取操作会立刻返回;若没有其他进程打开文件来读取,则写入操作会返回ENXIO错误
        没有使用O_NONBLOCK旗标时,打开FIFO文件读取操作会等到其他进程打开FIFO文件进行写入才能正常返回。同样,打开FIFO文件进行写入操作会等其他进程打开FIFO文件进程读取后才能正常返回

 综合案例 

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define FIFO "/home/linux/test/2"

int main(int argc,char *argv[])
{
	char buffer[80];
	int fd;
	unlink(FIFO);                 //unlink删除指定的文件,若文件存在则删除它,确保后边mkfifo建立的特殊文件不存在
	mkfifo(FIFO,0666);
	if(fork() > 0)
	{
		char s[] = "hello!\n";
		fd = open(FIFO,O_WRONLY);
		write(fd,s,sizeof(s));
		close(fd);
	}
	else
	{
		fd = open(FIFO,O_RDONLY);
		read(fd,buffer,80);
		printf("%s",buffer);
		close(fd);
	}

	return 0;
}

 运行结果

linux@ubuntu
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值