信号

信号是进程间相互传递消息的一种方法,只是用来通知某进程发生了什么事件,并不给进程传递任何数据。
#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. HTTP协议-----小白

    HTTP是一个属于应用层的面向对象的协议. ***OSI的7层从上到下分别是 7 应用层 6 表示层 5 会话层 4 传输层 3 网络层 2 数据链路层 1 物理层 HTTP协议的主要特点可概括如下: ...

  2. hdoj 1002 A+B(2)

    Problem Description I have a very simple problem for you. Given two integers A and B, your job is to ...

  3. Java 获取 Unix时间戳

    unix时间戳是从1970年1月1日(UTC/GMT的午夜)开始所经过的秒数,不考虑闰秒. 在大多数的UNIX系统中UNIX时间戳存储为32位,这样会引发2038年问题. 但是,因为需求是需要int类 ...

  4. 关于js单页面实现跳转原理以及利用angularjs框架路由实现单页面跳转

    还记得我们刚开始学习html时使用的锚节点实现跳转吗? <a href="#target">我想跳转至目标位置</a> <p>第一条</p ...

  5. LR11录制脚本时打不开浏览器,如何解决?

    请教一下各位大神,我安装的LR11,在录制脚本的时候打不开浏览器,已经试过了网上的方法还是不行,以下是搜到的方法: 无法打开IE的主要原因是,LR的注册信息被修改了,所以无法找到IE的路径. 解决这个 ...

  6. Ubuntu16.04下面配置java环境变量

    我在ubuntu 16.04下面配置java环境变量的时候,开始在网上查信息的时候,没太注意ubuntu的版本,结果在.bashrc下面设置,在.profile下面设置,都不成功, 后面才想起来搜索u ...

  7. textField设置输入文字距左边的距离

    1.设置tetxField的内边距 [self.yourTextField setValue:[NSNumber numberWithInt:5] forKey:@"paddingTop&q ...

  8. ubuntu 14 中tomcat的开机启动设置

    开机自启动,将要执行的语句写入/etc/rc.local. #!/bin/sh -e # # rc.local # # This script is executed at the end of ea ...

  9. HDU 4336 Card Collector (期望DP+状态压缩 或者 状态压缩+容斥)

    题意:有N(1<=N<=20)张卡片,每包中含有这些卡片的概率,每包至多一张卡片,可能没有卡片.求需要买多少包才能拿到所以的N张卡片,求次数的期望. 析:期望DP,是很容易看出来的,然后由 ...

  10. angular中的 ng-change

    <!DOCTYPE HTML> <html ng-app="myApp"> <head> <meta http-equiv="C ...