信号

信号是进程间相互传递消息的一种方法,只是用来通知某进程发生了什么事件,并不给进程传递任何数据。
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);//系统调用signal用来设定某个信号的处理方法
int kill(pid_t pid, int sig);//系统调用kill来向进程发送一个信号
int pause(void);//系统调用pause等待一个信号
还有alarm/setitmer等

管道

管道是Linux中很重要的一种通信方式,是把一个程序的输出直接连接到另一个程序的输入。管道是一个固定大小的缓冲区,写满时会默认被阻塞,读空时程序也会被阻塞。管道包括无名管道和有名管道两种。

  • 半双工,数据单向流动
  • 单独构成一种独立的文件系统,只存在于内存中
  • 数据的读出和写入都是单向的,一进程从管道缓冲区头部读,一进程写入管道缓冲区末尾

父子进程通信:

#include <unistd.h>
//参数数组包含pipe使用的两个文件描述符,fd[0]读管道,fd[1]写管道,用一般的write/read/close函数来读写关闭管道
int pipe(int fd[2]);

命名管道FIFO:

FIFO是一个特殊的设备文件,FIFO的路径名存在于文件系统中;不同进程间可以共享数据;使用完后FIFO将继续保存。用mkfifo创建FIFO文件后,一般的文件I/O函数(close、read、write、unlink等)都可用于FIFO。
#include <sys/types.h>
#include <sys/stat.h>
int mkfifo(const char* pathname, mode_t mode);

消息队列

消息队列是一个消息链表,存放在内核中并由消息队列标识符标识。
#include <sys msg="" h="">
int msgget(key_t key, int msgflg);//创建新消息队列或取得已存在消息队列
size_t msgrcv(int msqid, void* msgp, size_t msgsz, long msgtype, int msgflg);//从队列中取常用信息
int msgsnd(int msgid, const void* msgp, size_t msgsz, int msgflg)//将数据放到消息队列中</sys>

共享内存

两个或更多进程访问同一块内存,共享内存在各种进程间通信方式中效率最高。使用共享内存时,要注意多进程间的同步访问,读写互斥等。
  1. 分配共享内存
  2. 需要访问这块共享内存的每个进程将这个共享内存绑定到自己的地址空间
  3. 绑定共享内存的进程脱离共享内存
  4. 释放共享内存

牵涉到的函数:

#include <sys/ipc.h>
#include <sys/shm.h>
int shmget(key_t key, size_t size, int shmflg)//得到一个共享内存标识符或创建一个共享内存并返回标识符
void *shmat(int shmid, const void *shmaddr, int shmflg)//连接共享内存shmid,把共享内存映射到调用进程的地址空间,随后像本地空间一样访问,返回指向共享存储的指针
int shmdt(const void *shmaddr)//用来断开与共享内存的连接,禁止本进程访问此块内存,shmaddr是shmat返回的值
int shmctl(int shmid, int cmd, struct shmid_ds *buf)//完成对共享内存的控制,cmd为IPC_RMID为删除共享内存

信号量

信号量是一个计数器,代表资源可用数目,用于多进程对共享资源的同步访问。为了获得资源,进程需要执行的操作:1)尝试获得信号量。2)若此信号量的值为正,则进程可以使用资源,并将信号量减1;当进程不再使用资源时,信号量值加1。3)若此信号量值为0,进程进入休眠状态,直至信号量值大于0。Linux提供两种信号量:
  1. 内核信号量,由内核控制路径使用。
  2. 用户态信号量,包括POSIX信号量和SYSTEM V信号量。POSIX信号量分为有名信号量和无名信号量,有名信号量值存在文件中,无名信号量值保存在内存中。
#include <sys/sem.h>
//创建一个新的信号量或获得一个已存在的信号量。key表示创建或打开信号量集的键,num_sems表示创建的信号量集中的信号量个数,
//flag:指出函数的操作类型和读写权限IPC_CREAT如果信号量集不存在,则创建信号量集;IPC_EXCL/IPC_CREAT:如果信号量集已经存在,则调用失败;读写权限ugo(用户、组、其他)
int semget(key_t key, int num_sems, int sem_flags);
int semop(int sem_id, struct sembuf *sem_ops, size_t num_sem_ops);//改变信号量的值
int semctl(int sem_id, int sem_num, int command, ...);

总结:消息队列、信号量和共享内存这三种IPC,其结构都用一个非负整数的标识符加以引用,每个IPC对象都与一个键相关联(key_t长整型),键由内核转换成标识符。IPC结构在进程间的传递方式:1) 服务器进程指定键IPC_PRIVATE创建一个新IPC结构,将返回的标识符存放在某处以便客户进程取用;2)在一个公用头文件中定义一个客户进程和服务器进程都认可的键;3)客户进程和服务器进程认同一个路径名和项目ID,调用函数ftok将两个值变换为一个键。

三个get函数(msgget,semget,shmget)如果满足下列两个条件之一,则创建新IPC结构:1)key是IPC_PRIVATE,2)key当前未与特定类型的IPC结构相结合,并且flag中指定了IPC_CREAT位。

套接口

常用的网络通信方式,不再细说。

linux下进程间通信的更多相关文章

  1. 浅析Linux下进程间通信:共享内存

    浅析Linux下进程间通信:共享内存 共享内存允许两个或多个进程共享一给定的存储区.因为数据不需要在客户进程和服务器进程之间复制,所以它是最快的一种IPC.使用共享内存要注意的是,多个进程之间对一给定 ...

  2. Linux下进程间通信的六种机制详解

    linux下进程间通信的几种主要手段:        1.管道(Pipe)及有名管道(named pipe):管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道所具 ...

  3. Linux下进程间通信--消息队列

    消息队列的定义遍地都是,不想移驾,请看下文: 一.定义: 消息队列提供了一种从一个进程向另一个进程发送一个数据块的方法. 每个数据块都被认 为是有一个类型,接收者进程接收的数据块可以有不同的类型值.我 ...

  4. 【操作系统之三】Linux下进程间通信-IPC(Inter-Process Communication)

    管道(Pipe)及有名管道(named pipe):管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允许无亲缘关系进程间的通信:信号(Sign ...

  5. linux下进程间通信的机制

    今天突然想起了nginx解决惊群的方法,就是在多个进程间利用锁来保证同一时刻只能有一个worker进程在自己的epoll中加入监听的句柄,那么进程间是怎么共享变量的呢,下面就介绍一下共享内存 共享内存 ...

  6. Windows与Linux下进程间通信技术比较

    一般我们写的程序都是以单个进程的方式来运行的,比较少涉及到多进程.特别是在windows下,因为Windows是按照线程来分配CPU时间片的,线程是最小的调度单位,所以在Windows下更多的用到多线 ...

  7. Linux下进程间通信方式——信号量(Semaphore)

    1.信号量 信号量本质上是一个计数器(不设置全局变量是因为进程间是相互独立的,而这不一定能看到,看到也不能保证++引用计数为原子操作),用于多进程对共享数据对象的读取,它和管道有所不同,它不以传送数据 ...

  8. Linux下进程间通信--共享内存:最快的进程间通信方式

    共享内存: 一.概念: 共享内存可以说是最有用的进程间通信方式,也是最快的IPC形式.两个不同进程A.B共享内存的意思是,同一块物理内存被映射到进程A.B各自的进程地址空间. 进程A可以即时看到进程B ...

  9. Linux下进程间通信方式——共享内存

    1.什么是共享内存? 共享内存就是允许两个或多个进程共享一定的存储区.就如同 malloc() 函数向不同进程返回了指向同一个物理内存区域的指针.当一个进程改变了这块地址中的内容的时候,其它进程都会察 ...

随机推荐

  1. SQl server 关于重复插入数据的测试

    最近发布的脚本,有那种防止重复插入数据(包括存在时更新,不存在是插入的处理,判断的方向可能与下面的示例相反) 使用类似下面的 SQL declare @id int, @value int if no ...

  2. 正确获得android设备的IP地址

    网上此类获得android设备IP地址相关的文章有不少,有一篇是比较通用的,但有一个问题:有些设备默认的是IPv6的地址,那段代码获得的就是IPv6的地址.但这显然不是我们想要的,我们需要的是IPv4 ...

  3. c#利用WebClient和WebRequest获取网页源代码的比较

    前几天举例分析了用asp+xmlhttp获取网页源代码的方法,但c#中一般是可以利用WebClient类和WebRequest类获取网页源代码.下面分别说明这两种方法的实现. WebClient类获取 ...

  4. Html/Css(新手入门第三篇)

    一.学习心得---参考优秀的网页来学习. 1我们只做的静态网页主要用的技术?html+css 只要网上看到的,他的源代码公开的.[1].先去分析,他们页面是如何布局(结构化)[2].再试着去做一下,- ...

  5. sql连着function使用

    create function fun002(@thename varchar()) returns int as begin declare @count int select @count=cou ...

  6. linux下配置nginx使用service nginx start 服务

    解压出来后执行 mkdir /var/tmp/nginx/client/ -pv 接下来我们简单的为它提供一个服务脚本吧! # vim  /etc/init.d/nginx 新建文件/etc/rc.d ...

  7. 数位DP

    题意:(hdu 4734) 我们定义十进制数x的权值为f(x) = a(n)*2^(n-1)+a(n-1)*2(n-2)+...a(2)*2+a(1)*1,a(i)表示十进制数x中第i位的数字. 题目 ...

  8. springboot使用之四:错误页面404处理建议

    每个项目可能都会遇到404,403,500等错误代码,如没有错误页面,则会给用户一个很不友好的界面,springboot项目同样也存在这个问题. 但在官方文档并没有相关配置信息,这就要求我们自己来实现 ...

  9. 领域模型驱动设计(Domain Driven Design)入门概述

    软件开发要干什么: 反映真实世界要自动化的业务流程 解决现实问题 领域Domain Domain特指软件关注的领域 在不能充分了解业务领域的情况下是不可能做出一个好的软件 领域建模 领域模型驱动设计 ...

  10. python 延迟绑定

    def multipliers(n): funcs = [] for i in range(n): def f(x): return x * i funcs.append(f) return func ...