进程通信又称IPC

IPC方法

方法:管道(最简单)

信号(开销最小)

共享映射区/共享内存(无血缘关系)

本地套接字(最稳定)

Linux文件类型: -   文件

d  目录

l   符号链接

s   套接字        伪文件

b    块设备       伪文件

c字符设备       伪文件

p管道               伪文件

管道

其本质是:

1、伪文件,实质为内核缓冲区

2、由两个文件描述符表示,一个表示读端,一个表示写端

3、数据从读端流入,从写端流出

管道原理:内核使用环形队列机制,借助内和缓冲区实现

管道局限性:1、数据自己读不能自己写

2、数据一旦被读走,便在管道中不存在,不可反复读取

3、由于管道采用半双工通信方式,数据只能在一个方向上流动

4、只有公共祖先的进程间才能使用管道

匿名管道

适用于:只有公共祖先的进程

pipe函数

作用:创建管道

头文件

函数模型

#include int pipe(int pipefd[2])

pipefd[2]:传出参数

读端、写端由自己决定

返回值:0 成功

非0 错误代码

管道读写规则:

读管道:当管道中有数据,read返回实际读到的字节数

当管道中没有数据,若写端全关闭,read函数返回0

若任有写端打开,阻塞等待

写管道:当读端全关闭时,进程异常终止(SIGPIPE信号)

有读端打开,若管道未满,写数据,返回写入字节数

若管道已满,阻塞(少见)

获取管道缓冲区大小:命令 ulimit -a

fpathconf函数

作用:获取管道缓冲区大小

头文件

#include 函数原型

long int fpathconf(int fd,int parameter)

paramter:__PC_PIPE_BUF

#define _GNU_SOURCE

#include #include int pipe2(int pipefd[2], int flags)

优点:实现手段简单

缺点:单向通信,只有血缘关系进程间使用

有名管道

命名管道是一种特殊类型的文件。

命名管道和匿名管道区别:

管道应用的一个限制就是只能在具有亲缘关系的进程间通信,命名管道可以再不相关的进程间交换数据。

mkfifo函数

作用:创建一个FIFO文件

头文件

#include 函数原型

int mkfifo(const char *filename, mode_t mode)

mode:权限

返回值:成功 0

-1 失败

可多读端,多写端

共享内存

命名映射区

mmap函数

作用:

头文件:

#include 函数原型

void* mmap(void *addr, int length , int port , int flag, int fd, off_t offset)

参数:

addr:建立的映射区的首地址,由Linux内核指定,直接传NULL

length:创建映射区的大小

port:映射区的权限

PORT_READ

PROT_WRITE

PROT_READ| PROT_WRITE

flags:标志为参数(常用于设定更新物理区域,设置共享,创建匿名映射区)

MAP_SHARED:会将内存所做的修改反映到硬盘

MAP_PRIVATE

fd:文件描述符

offset:映射文件的便宜为4K倍数

返回值:成功 返回映射区首地址

失败 MAP_FAILD 宏

munmap函数

头文件

#include 函数原型

int munmap(void* addr, size_t length)

使用注意事项:

1、创建映射区过程中,隐含一次对文件的读操作

2、当MAP_SHARED,要求映射区的权限<= 文件打开权限。而MAP_PRIVATE则无所谓,因为mmap中的权限是对内存的限制

3、映射区的释放与文件关闭无关,只要映射建立成功,文件可以立即关闭。

4、当映射文件大小为0时,不能创建映射区。

5、munmap传入的地址一定是mmap的返回地址。坚决抵制自增操作

6、文件偏移量必须是4096的倍数

7、mmap创建映射区出错率非常高,一定要检查返回值,确保映射区建立成功后在操作

匿名映射区

映射区的缺陷是,每次都创建映射区时一定要依赖一个文件才能实现,通常要open,unlink,close等比较麻烦,因此可以利用匿名映射来代替。

int *p = mmap(NULL, 4, PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,-1,0)

mmap无血缘关系进程间通信

信号

基本的属性

1、简单

2、不能携带大量信息

3、满足某个特定条件才发送

与信号相关的事件和状态

产生信号:

按键产生

系统调用   kill    raise   abort

软件条件    定时器  alarm

命令条件   kill命令

递答:递送且到达

未决:产生和递答之间状态

信号处理方式:

1、执行默认动作

2、忽略(丢弃)

3、捕捉(由用户处理函数)

信号4要素

1、编号      2、名称      3、时间        4、默认处理动作

查看man 7 signal可以查看帮助

产生信号函数

kill函数/命令

kill命令:kill -SIGKILL pid

头文件

#include #include 函数原型

int kill(pid_t pid, int sig)

参数:

pid:>0 发送信号给指定进程

=0 发送信号给 调用kill函数进程属于同一进程组的所有进程

<0 取pid的绝对值发给对应进程

=-1 发给进程 有权限发送的系统中所有进程

raise函数

作用:给当前进程发送信号

头文件

#include #include 函数模型

int raise(int sig)

abort函数

作用:给当前进程发送 异常终止信号 SIGABRT

头文件

#include #include

函数原型

int abort(void)

软件条件产生信号

alarm函数

每个进程有且只有唯一一个定时器

头文件:

#include 函数原型

unsigned int alarm(unsigned int seconds)

返回值:

返回0或剩余的秒数,通常alarm(0)返回闹钟剩余秒数,无失败,支持秒级,与进程状态无关

setitimer函数

作用:设置定时器,精度us级

头文件

#include 函数原型

int getitimer(int which, struct itimerval *curr_value)

int setitimer(int which, const struct itimerval *new_value, struct itimerval *old_value)

参数:

which:制定定时方式

自然定时 ITIMER_REAL SIGALRM 计算自然时间

虚拟空间计时(用户空间) ITIMER_VIRTUAL SIGVTALRM 只计算进程占用CPU时间

运行时间计时(用户+内核) ITIMER_PROF ITIMER_PROF 计算占用CPU及执行系统调用的时间

struct itimerval{

struct timeval it_interval; //下一次定时 ,,两次任务间隔

struct timeval it_value; //当前定时值,用来定时时长

};

struct timeval{

time_t tv_sec; //秒数

suseconds_t tv_usec; //微秒数

};

信号集操作函数

信号集设定

sigset_t set; //无符号长整形 typedef unsigned long sigset_t

int sigemptyset(sigset_t *set); 将某个信号请0

int sigfillset(sigset_t *set) 将某个信号集置1

int sigaddset(sigset* set, int signum) 将某个信号加入信号集

int sigdelset(sigset* set, int signum) 将某个信号清除信号集

int sigismember(const sigset_t* set, int signum) 判断某个信号在信号集中

sigprocmask函数

作用:屏蔽信号,解除信号,本质读取或修改进程的信号屏蔽字,严格注意:屏蔽信号:只是将信号处理延后执行,而忽略表示将信号丢弃

头文件

函数原型

int sigprocmask(int how, const sigset_t * set, sigset_t *oldset)

参数;set 传入参数,位图,1表示屏蔽

oldset  传出参数 用来保存旧的信号屏蔽集

how:假设当前信号屏蔽字mask

SIG_BLOCK,set表示需要屏蔽的信号

SIG_BLOCK,set表示需要解除的屏蔽信号

SIG_SETMASK,代替原始屏蔽的新的屏蔽

sigpending函数

作用:读取当前进程的未决信号集

函数原型

int sigpending(sigset_t *set)

参数:set 传出参数

信号捕捉

signal函数

头文件

#include 函数原型

typedef void (*sighandler_t)(int)

sighandler_t signal(int signum, sighandler_t handler)

返回值:SIG_ERR 错误

sigaction函数

头文件

#include 函数原型

int sigaction(int signum, const struct sigaction * act, struct sigaction *oldact)

作用:修改信号处理动作

参数

struct sigaction{

void (*sa_handler)(int) //函数名

void (*sa_sigaction)(int, siginfo_t *, void *) //当sg_flags被指定为SA_SIGINFO时,使用该型号处理程序(很少使用)

sigset_t sa_mask //用于 处理函数在被调用时屏蔽生效

int sa_flags //0表示默认属性

void (*sa_restorer)(void) //废弃,已不用

};

信号捕捉特性

1、阻塞的信号不支持排队,产生多次,只记录一次。

竞态条件

pause函数

作用:调用该函数可以使进程主动挂起,等待信号唤醒

头文件

#include 函数原型

int pause(void)

返回值:

1、如果信号的默认处理动作是终止进程,则进程终止,pause函数没有机会返回

2、如果信号的默认处理是忽略,进程继续挂起,pause函数不返回

3、如果信号的处理动作是捕捉,则调用完信号处理函数之后,pause函数返回-1

4、pause收到的信号不能被屏蔽,如果被屏蔽就不能唤醒

信号传参

发送信号传参

sigqueue函数对应kill函数,但可想指定进程发送信号的同时携带参数。

sigqueue函数

头文件

函数原型

int sigqueue(pid_t pid, int sig, cinst union sigval value);

union sigval{

int sigval_int;

void *sival_ptr;

};

捕捉函数传参

sigaction函数

见信号捕捉函数

当注册信号捕捉函数,不适用sa_handler 而使用 sa_sigaction.

进程组

进程组操作函数

getpgrp函数

获得当前进程组ID

pid_t getpgrp(void)

getpgid函数

获取指定进程的进程组ID

pid_t getpgid(pid_t pid)

setpgid函数

改变进程默认的所属进程组,通常加入一个现有进程组或创建型进程组

int setpgid(pid_t pid, pid_t pgid)

会话

创建会话

创建会话有6点:

1、调用进程不能是进程组租场,新进程变为会长

2、该进程变为新进程组组长

3、需要root权限(Ubuntu不需要)

4、新会话丢弃原有控制终端,该回话没有控制终端

5、该调用进程是组长进程

6、建立会话时,先调用fork,父进程种子,子进程调用setpgid

getsid函数

获得进程的会话ID

pid_t getsid(pid_t pid)

srtsid函数

int setsid()

守护进程

守护进程/精灵进程:Linux后台服务进程,无终端,周期性执行某种任务或等待处理某些发生的条件。

创建守护进程,最关键的是调用setsid函数创建一个新的session,并且成为session leader

创建守护者模型

1、创建子进程,父进程退出,所有工作都脱离了控制终端

2、在子进程中创建新的会话

setsid函数

3、改变当前目录为根目录   chdir函数

防止占用可卸载的文件系统,也可以换成其他路径

4、重设文件权限掩码

umask函数

防止继承的文件创建屏蔽字拒绝某些权限,增加灵活性

5、关闭文件描述符

继承的打开文件不会用到,浪费资源,不关闭 0,1,2   而是重定向  >  /dev/null                      dup2()

6、开始执行守护进程核心

7、守护进程退出处理

linux进程通信发送方式,Linux服务器编程——Linux系统编程之进程通信相关推荐

  1. linux服务器开发二(系统编程)--线程相关

    线程概念 什么是线程 LWP:Light Weight Process,轻量级的进程,本质仍是进程(在Linux环境下). 进程:独立地址空间,拥有PCB. 线程:也有PCB,但没有独立的地址空间(共 ...

  2. linux推送日志到日志服务器,linux把日志发送到日志服务器上

    上一篇我们介绍了rsyslog配置文件.在现网环境中,无论是为了把日志存储更长的时间还是为了分析日志的方便性,我们通常会把日志发送到日志服务器或是日志收集分析系统上.接下来我们介绍一下如何配置. 实验 ...

  3. linux系统编程_Linux系统编程:进程间通信

    进程的重要性对于编程人员来说,至关重要,那么,进程间是如何通信的呢?在一个大的项目中,进程间的通信有哪些方式,这对于我们程序员来说也是很重要的一个点?那么本节我们就来聊聊进程间通信的方式,以及各自的优 ...

  4. linux上无法发送163邮件,如何在linux中发送邮件,使用163邮箱发信。

    linux中,可以使用mail命令往外发送邮件,在使用前,只需要指定如下简单配置即可,这里演示用  163.com    邮箱发送至 qq.com 编辑 /etc/mail.rc,写入下方的参数 se ...

  5. unix环境高级编程 pdf_UNIX系统编程宝典,每一本都值得程序员珍藏

    这几本UNIX系统编程宝典,重印无数次,几代程序员都视如珍宝的几本书,小编在出版圈里快十年了,见证了这本书图灵版.异步社区版的出版.营销,对这套书倾注了一定的感情.今天继续分享给你们,好书总会有人还不 ...

  6. linux 多线程客户端服务端通信,[转载]多线程实现服务器和客户端、客户端和客户端通信;需要代码,留言...

    一.实验名称 动手打造自己的 IM 二.实验目的 1本次实验旨在锻炼大家的Socket编程能力,以日常生活中广泛使用的IM软件为背景,培养大家对于网络编程的兴趣. 2.通过本次实验,培养linux环境 ...

  7. linux 无密码登录另一台服务器,ECS Linux服务器ssh免密码登录另外一台服务器的具体设置...

    若有多台linux服务器,为方便起见,服务器之前可设置免密码ssh登录,具体操作参考如下所示: 1 .登录其中一个服务器,执行ssh-keygen -t rsa,按3次回车,将会生成公钥和私钥文件id ...

  8. linux脚本怎么发送到桌面,如何在Linux上使用Zenity创建简单的图形Shell脚本

    Zenity使用单个命令为shell脚本添加了图形界面. Shell脚本是自动化重复任务的好方法,但是它们通常只限于终端 - Zenity将它们从终端中导出到桌面上. 我们已经介绍了过去的shell脚 ...

  9. php soecket服务器搭建_Linux系统编程(32)—— socket编程之TCP服务器与客户端

    TCP协议的客户端/服务器程序的一般流程 aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAgQAAAJmCAYAAAAjPpjHAAAgAElEQVR4A ...

最新文章

  1. unittest笔记
  2. 开发运维效率提升 80%,计算成本下降 50%,分众传媒的 Serverless 实践
  3. 【sprinb-boot】改造成 spring-cloud 项目
  4. 全局路径规划A star的Matlab实现
  5. ubuntu 14.04 linux下wifi驱动安装使用的一些笔记
  6. org.slf4j.Logger中isTraceEnabled(),isDebugEnabled(),isInfoEnabled(),isWarnEnabled(),isErrorEnabled()
  7. matlab查看RGB图像矩阵数值
  8. 如何解决“本地编辑,更新时传入删除”消息
  9. [转载] Java异常处理中Try-Catch-Finally中常见的笔试题
  10. Python的argparse
  11. ArcGIS操作小技巧(七)之制作漂亮的萤火虫图
  12. 我不曾忘记的初心-大厂小厂
  13. 苹果cmsv10自适应高仿时光影院视频网站免费模板
  14. 小程序版聊天室|聊天小程序|仿微信聊天界面小程序
  15. python监听键盘事件pyhook用法_python 监听键盘事件pyHook
  16. linux编译 __stdcall,Linux中是否有STDCALL?
  17. IE浏览器无法打开HTTPS解决办法
  18. shim和polyfill
  19. Unity制作简单的精灵图动画(新手向)
  20. windows自带hyperv安装虚拟机ubuntu与分辨率修改

热门文章

  1. sublime text3 package control 报错
  2. 第 52 章 Web Server Optimization
  3. 为什么Docker是云计算必然的现在和未来
  4. linux syslog 笔记
  5. 五个在线图形工具创建简单的设计元素
  6. x264_param_t参数注解
  7. 【图像处理】——opencv常用函数
  8. 最优化课堂笔记01: 第一章 最优化的基本概念
  9. 将数组作为参数,调用该函数时候给的是数组地址还是整个数组
  10. 图片向上滚动字幕代码html,如何通过制作滚动字幕的软件实现这种片尾的向上滚动字幕效果...