进程间通信(一)

进程间通信(IPC)

进程间通信的类型:

半双工管道(FIFO)、全双工管道(命名全双工管道)、消息队列、信号量、共享内存、套接字(多机其它为单机)

IPC的通信方式:

管道(包括无名管道、命名管道)
消息队列
信号量
共享存储
Scoket
Streams
等。
其中,Scoket和Stream支持不同主机上的两个进程IPC。

一、管道

管道,通常指无名管道,是UNIX系统最古老的形式。

1、特点

1)半双工的(即数据只能在一个方向上流动),具有固定的读端和写端。[管道中的数据读走就没有了,可以类似水管想象一下]
2)只能用于具有亲缘关系的进程之间的通信(父子进程或兄弟进程)
3)是一种特殊的文件,对于他的读写可以使用普通的read、write等函数。但是它不是普通文件,并不属于其它任何文件系统,并且只存在于内存中。

2、原型
#include<stdio.h>
int pipe(int fd[2]);	//有返回值,若成功返回0;失败返回-1;

当一个管道建立时,它会创建两个文件描述符;

fd[0]为读而打开,

fd[1]为写而打开。

3、栗子
#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<stdlib.h>
int main(){
    int fd[2];
    int pid;
    char buf[24];
    if(pipe(fd)==-1){
        printf("creat pipe failed\n");
    }
    pid=fork();
    if(pid<0){
        printf("create child failed\n");
    }else if(pid>0){
        printf("this is father\n");
        close(fd[0]);		//关闭读端
        write(fd[1],"hello everyone",strlen("hello everyone"));		//开启写端进行写数据
        wait();		//父进程等待子进程
    }else{
        printf("this is child\n");
        close(fd[1]);		//关闭写端
        read(fd[0],buf,24);		//打开读端,读buf里数据
        printf("read from father %s\n",buf);
        exit(-1);		//子进程退出
    }
	return 0}
命名管道FIFO

FIOFO,亦称命名管道,是一种文件类型。

1、特点

1)可在无关的进程之间交换数据,与无名管道不同;
2)有路径名,以一种特殊设备文件形式存在于文件系统中。

2、原型

查找mkfifo在man手册第三页

#include <sys/stat.h>
int mkfifo(const char *pathname,mode_t mode);	//返回值,成功返回0;失败返回-1;

mode参数与open函数中的mode相同,一旦创建了一个FIFO,就可以用一般的文件I/O函数操作它。

3、栗子

若指定了O_NONBLOCK,则只读open立即返回;而只写open将出错返回-1,如果没有进程已经为只读而打开该FIFO,其errno置ENXIO。

#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<errno.h>
int main(){
    int fd=mkfifo("./file",0600);	//创建一个file文件,可读可写
    if((fd==-1)&&errno==EEXIST){	//判断是否创建成功
        printf("mkfifo failed\n");
        perror("why:");		//打印失败的原因
    }else{
        printf("mkfifo success\n");
    }
    return 0;
}

若没有指定O_NONBLOCK(默认),只读open要阻塞到某个其它进程为写而打开此FIOFO;同理,只写open要阻塞到某个其它进程为读而打开它。

这是一个read.c程序
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<errno.h>
#include<fcntl.h>
int main(){
    char buf[32]={0};
    int m=mkfifo("./file",0600);
    if((m==-1)&&errno!=EEXIST){
        printf("mkfifo failed\n");
        perror("why:");
    }
    int fd=open("./file",O_RDONLY);
    printf("open success\n");
    int nread=read(fd,buf,32);
    printf("read %d from fifo\r context:%s\n",nread,buf);
    close(fd);
    return 0;
}
这是一个write.c程序
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
int main() {
    char *str = "hello,fifo!";
    int fd = open("./file", O_WRONLY);
    printf("write open success\n");
    write(fd, str,strlen(str));
    close(fd);
    return 0;
}

先运行read.c程序,接着运行write.c程序就可以实现两个端的数据交互。
剩余的通信方式且听下回分解!
进程间通信(二)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值