美文网首页
Linux系统编程(四) ------ 进程间通信

Linux系统编程(四) ------ 进程间通信

作者: 穹蓝奥义 | 来源:发表于2017-04-06 15:11 被阅读0次

进程是设计和分析操作系统的有力工具。然而不同的进程之间.即使是具有家族联系的父子进程.都具有各自不同的进程映像。由于不同的进程运行在各自不同的内存空间中.一方对于变量的修改另一方是无法感知的,靠自己的空间无法资源共享,只能由系统单独提供,不同系统平台有不同方式。因此.进程之间的信息传递不可能通过变量或其它数据结构直接进行,只能通过进程间通信来完成。

进程间通信的方法有:

有名管道Pipe
无名管道fifo
共享内存shared memory
内存映射mmap
同步信号量semaphore
套接子socket 
消息队列mesgq

管道

管道是由内核提供的空间,容量有限。读写的方向性:读走、写入。

一、无名管道

#include <unistd.h>
int pipe(int pipefd[2]);   //即两个值,代表读写

无名管道不对应文件类型,只存在于内存中,只能在亲缘进程间。文件标识符的打开关闭。安全性,资源分配合理调度。
过程:

1、内核给进程分配资源,读写指针分别指向读写两端。
2、fotk()后子进程也如此,读写指针指向读写两端。
3、一共4个指针,分别各关闭一个指针,让一个只写,让一个只读,形成管道。

注意:

1.必须是父子进程或亲缘进程。
2.所分配空间可能满,写等待,
3.等全读走(非读取!),再写。

二、有名管道

有名管道,文件类型p,无需父子进程,正经的管道文件。
在磁盘建立管道文件,但不存储数据,只起传递作用,让其他进程可以打开,可在任意进程间操作。数据进内核通过管道文件去到另一个文件。
读操作取决于管道内有无数据,有什么取走什么。先发先收。读写端都要存在,特别是写端一定存在。read()一读到EOF就退出。
写是主动的、有返回值的,内核回应直接关闭,写还有准备过程,如等待输入。
读是从属动作没有获得返回值,内核只会写不进、不会关闭,读是整体读取。
接受的人负责创建,管道文件一般大小都为0,并发让线程进程按角色分工。

创建管道文件

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

三、共享内存

共享内存,效率最高,在内存中提供空间,两个进程同时映射,无需切换到内核态(不使用系统调用),没有额外的复制操作。本身无保护和互斥机制,无同步能力,配套使用同步的信号量,主要作用是同步,依然不能读取数据。

#include <sys/types.h>
#include <sys/ipc.h>
key_t ftok(const char *pathname, int proj_id);

pathname是指定路径,filename是指定的文件名,这个文件必须存在且可以访问。
id是子序号,它是一个8bit的整数。即范围是0~255。
当函数执行成功,则会返回key_t键值,否则返回-1。在一般的UNIX中,通常是将文件的索引节点取出,然后在前面加上子序号就得到key_t的值。
ftok根据路径名,提取文件信息,再根据这些文件信息及project ID合成key,该路径可以随便设置。但该路径是必须存在的,ftok只是根据文件inode在系统内的唯一性来取一个数值,和文件的权限无关。

分配
#include <sys/ipc.h>
#include <sys/shm.h>
//得到一个共享内存标识符或创建一个共享内存对象
int shmget(key_t key, size_t size, int shmflg)
绑定
#include <sys/types.h>
#include <sys/shm.h>
void *shmat(int shmid, const void *shmaddr, int shmflg);
int shmdt(const void *shmaddr);

添加:内存拷贝函数
#include <string.h>
void *memcpy(void *dest, const void *src, size_t n);

脱离
int shmdt(const void *shmaddr);
释放
int shmctl(int shmid, int cmd, struct shmid_ds *buf);

此函数函数本身不仅仅用来删除,主要是用于控制。

shmctl(shmid, IPC_RMID, 0);

作用是从系统中删除该恭喜存储段。因为每个共享存储段有一个连接计数(shmid_ds结构中的shm_nattch),所以除非使用该段的最后一个进程终止与该段脱接,否则不会实际上删除该存储段。
Linux进程间通信(7)

四、同步信号量

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>

分配和销毁/获取和释放

int semget(key_t key, int nsems, int semflg);
int semctl(int semid, int semnum, int cmd, ...);
//根据cmd的值不同,传不同的值

等待和投递

int semop(int semid, struct sembuf *sops, unsigned nsops); 
//第一个参数信号量集的id,参数二和参数三一起,结构体首地址和个数,成为结构体数组,
//每一个结构体对应一个操作,结构体首地址和个数。semop()对数组诸葛处理。
//当前信号量的值+op值,op<0对应wait,op>0对应post。

保护用锁,同步用信号量,异步用信号

共享内存,消息队列,信号量三者都是找一个中间介质,来进行通信的,系统资源很多,要找有“唯一属性”的,就是文件的设备编号和节点,它是唯一的,但是直接用它来作识别好像不太好,不过可以用它来产生一个号就是ftok()。

相关文章

  • 【linux/unix系统编程手册笔记】系统编程概念

    【Linux/Unix系统编程手册笔记】系统编程概念 1.系统调用 系统调用: 创建新进程 执行I/O 进程间通信...

  • Linux系统编程(四) ------ 进程间通信

    进程是设计和分析操作系统的有力工具。然而不同的进程之间.即使是具有家族联系的父子进程.都具有各自不同的进程映像。由...

  • 初识Linux

    文章目录 一、熟悉Linux环境 二、shell编程 三、Linux进程控制与通信管理 四、文件系统与磁盘管理 五...

  • Linux系统编程:Inter-Process Communic

    一、IPC——进程间通信 Linux系统提供的进程间通信的手段: 消息传递类:信号 匿名管道 命名管道 socke...

  • c进程间通信IPC以及信号概述

    linux系统内核提供了进程间通信的机制 IPC(InterProcess Communication) IPC的...

  • 进程间通信

    Android系统是基于Linux内核的,而Linux内核继承和兼容了丰富的Unix系统进程间通信(IPC)机制。...

  • 操作系统第二次上机实验-进程通信

    实验题目:进程通信 实验目的 熟练使用 Linux 的 C 语言开发环境 掌握 Linux 操作系统下的并发进程间...

  • 进程间的通信

    进程间的通信主要分为本机器进程间的通信和不同机器间进程的通信。本文主要描述本机进程间的通信。 一、传统Linux的...

  • Linux网络编程:Socket编程基础

    一、什么是网络编程? 网络编程是进程间通信的延续。IPC:同一台电脑上同一系统里的两个进程间通信。网络:不同电脑上...

  • Android Binder通信

    下面先看看Binder通信的模型图: Binder是Android系统进程间通信(IPC)方式之一。Linux已经...

网友评论

      本文标题:Linux系统编程(四) ------ 进程间通信

      本文链接:https://www.haomeiwen.com/subject/zdrsbttx.html