进程通信linux代码c语言,【linux】进程间的通信简介(c语言编程)

进程间的通信简介

一、进程间的通信

1、linux下进程间通信概述

进程间通信就是在不同进程之间传播或交换信息。

进程间通信(IPC interprocess communication)主要包括以下几种:

1、管道及有名管道

管道:具有亲缘关系进程间的通信

有名管道:可以在许多不相关的进程之间进行通信

2、信号(signal):用于通知接收进程有某种事件发生

3、报文(message)队列(消息队列):消息队列是消息的链接表

4、共享内存:使多个进程可以访问同一块内存空间

5、信号量:作为进程间以及同一进程不同线程之间的同步手段

6、套接字(socket):可用于不同机器之间的进程间通信。

2、管道通信(连接一个进程的标准输入到另一个进程的标准输出的方法)

1、管道

当进程创建一个管道时,系统内核设置了两个管道可以使用的文件描述符。(write,read)

特点:

管道是半双工的

只能用于具有亲缘关系的进程

单独构成一种独立的文件系统

数据的读出和写入:(FIFO)写入的内容每次都添加在管道缓冲区的末尾,

并且每次都是从缓冲区的头部读出数据

(1)管道的创建

pipe()函数用于创建无名管道,当管道创建时会创建fd[0]和fd[1]两个文件描述符

函数原型:

int pipe(int fd[2])

fd[2]: fd[0]固定用于读管道,fd[1]固定用于写管道

返回值:成功——返回0; 失败——返回-1

(2)管道的关闭

close(): 关闭了fd[0]和fd[1]就关闭了管道

(3)管道的读/写操作

写操作:close(fd[0]);//关闭读取端

sleep(3);//确保已关闭相应的读描述符

write(fd[1],string,strlen(string));//通过写端将字符串写入管道

close(fd[1]);//关闭写描述符

读操作:close(fd[1]);//关闭写入端

read(fd[0],readbuffer,sizeof(readbuffer));//从管道中读取字符串

printf("%s",readbuffer);

close(fd[0]);//关闭读描述符

2、标准流管道

创建管道:FILE * popen(char * command, char * type)

command: 启动shell后执行的命令

type: 管道中数据流的方向w/r,不能同时为读和写(type只以第一个字符代表的方式打开)。

关闭管道:int pclose(FIFE * stream);

读写:fputs函数和fputc函数

3、有名管道(FIFO管道)

有名管道指创建的管道文件是有文件名的,任何程序都可以通过文件名或路径名与这个文件挂上钩

FIFO管道不是一个临时对象,而是在文件系统中作为一个特殊的设备文件而存在的实体。

(1)FIFO的创建

FIFO文件即”先进先出“文件,

创建方法:

mknod MYFIFO p

mkfifo a = rw MYFIFO

以上的两个命令执行同样的操作,但其中有一点不同。mkfifo提供一个在创建之后改变FIFO文

件存取权限的途径,而mknod需要调用命令chmod。

mkfifo函数原型:

int mkfifo(const char * pathname, mode_t mode)

pathname: 将在文件系统中创建的一个专用文件

mode:规定FIFO的读/写权限

返回值:成功——返回0;失败——返回-1

(2)使用

有名管道可以用于任意两个进程间通信。由于管道都是单向的,因此双方通信需要两个管道。

示例:

写入数据:mkfifo(namedpipe, 0777);//创建管道

pipe_fd = open(namedpipe, O_WRONLY);//以只写方式打开

sour_fd = open(sourtxt, O_RDONLY);//以只读方式打开源文件

bytes_read = read(sour_fd, buffer, sizeof(buffer));

buffer[bytes_read] = '\0';

while(bytes_read > 0) {//向管道写入数据

write(pipe_fd, buffer, sizeof(buffer));

bytes_read = read(sour_fd, buffer, sizeof(buffer));

buffer[bytes_read] = '\0';

}

读取数据:pipe_fd = open(namedpipe, O_RDONLY);//以只读方式打开管道

dest_fd = open(desttxt, O_WRONLY|O_CREAT, 0664);

bytes_read = read(pipe_fd, buffer, sizeof(buffer));

do {//从管道读出数据到目标文件

count = read(pipe_fd, buffer, sizeof(buffer));

write(dest_fd, buffer,sizeof(buffer));

} while (count > 0)

三、共享内存通信

共享内存:最有用的进程间通信方式,也是最快的IPC形式。两个不同进程A、B共享内存的意思是 ——

同一块物理内存被映射到进程A、B各自的进程地址空间。进程A可以即时看到进程B对共享内存中数据的

更新,反之亦然。由于多个进程共享同一块内存区域,必然需要某种同步机制(互斥锁、信号量)

对于系统V共享内存,主要有以下几个API:shmget(),shmat(),shmdt(),shmctl()

shmget(): 获取共享内存区域的ID,不存在指定共享区域则创建相应的区域

shmat():把共享内存区域映射到调用进程的地址空间中去

shmdt():接触进程对共享内存区域的映射

shmctl():实现对共享内存区域的控制操作

函数原型:

int shmget(key_t key, int size, int shmflg)

key:IPC结构的键值,通常取常量IPC_PRIVATE

size: 共享内存区的大小(新建时必须制定size大小,引用已有的区域,则size设为0)

shmflg:权限位,可以用八进制表示

返回值:成功——返回共享内存区域标识符ID,即shmid;出错——返回-1

char * shmat(int shmid, const void * shmaddr, int shflg)

shmid: 通过shmget得到的共享内存区标识符ID

shmaddr:将共享内存映射到指定位置。0 —— 表示映射到调用进程的地址空间

shmflg: 选项位,设置权限,常用选项是SHM_RDONLY(只读),默认为0(读写)。

返回值:成功——返回被映射的段地址,失败——返回-1

(使用以上两个函数即可以使用这段共享内存了,也就是可以使用不带缓冲的I/O读/写命令对

其进行操作)

int shmdt(const void * shmaddr)

shmaddr: 表示被映射的共享内存段地址

返回值:成功——返回0;失败——返回-1

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值