一、什么是进程线程?

进程通信:在用户空间实现进程通信是不可能的,通过linux内核通信;
线程通信:可以在用户空间就可以实现,可以通过全局变量通信。

进程间通信如下:

线程间通信如下:

二、进程间通信方式有哪些?

 单机模式下的进程通信(只有一个linux内核)管道通信:无名管道、有名管道(文件系统中有名)信号通信:信号(通知)包括:信号的发送、信号的接收和信号的处理。IPC(Inter-Process Communication)通信:共享内存、消息队列和信号灯。socket通信:存在于一个网络中两个进程之间的通信(两个Linux内核)。

进程间通信都是基于文件IO思想。

三、管道通信

1、无名管道(pipe)

管道文件是一个特殊的文件,由队列来实现的。
在文件IO中创建一个文件或打开一个文件是由open函数来实现的,它不能创建管道文件。
只能用 pipe 函数来创建管道。int pipe(int fd[2]);     -----> unistd.h
参数:得到的文件描述符,读端fd[0]用来读,写端fd[2]用来写。
返回值:成功:0;失败:-1。注意:1)管道是创建在内存中的,进程结束,空间释放,管道就不存在了;2)管道中的大小,读完了就不存在了;3)如果管道中没有东西,则会阻塞;4)如果管道中写满,再写时会进入写阻塞。无名管道的缺点:不能实现不是父子进程(有亲缘关系)之间的通信。

2、有名管道 (mkfifo)–>管道文件(p)

所谓有名,即文件系统中存在这个一样文件节点,每一个文件节点都有一个inode号,
而且这是一个特殊的文件类型:p 管道类型。
1、创建这个文件节点,不可以通过open函数创建,open函数只能创建普通文件,不能创建特殊的文件(管道-mkfifo,套接字-socket,字符设备文件-mknod,块设备文件-mknod,符号链接文件-ln -s,目录文件mkdir)2、管道文件只有inode号,不占磁盘块空间,和套接字、字符设备文件、块设备文件一样。普通文件和符号链接文件及目录文件,不仅有inode号,还占磁盘块空间。3、mkfifo 用来创建管道文件的节点,没有在内核中创建管道。只有通过open函数打开这个文件时才会在内核空间创建管道。
int mkfifo(const char *filename, mode_t mode);   创建管道文件 ---->sys.stat.h
参数:1)管道文件名;2)文件权限,与umask有关。
返回值:成功:0;失败:-1。有名管道可以实现无亲缘关系之间的进程通信。

四、信道通信

1、信号的发送(发送信号进程)

int kill(pid_t pid, int sig);     ---->#include <signal.h>、#include <sys/types.h>参数:1)pid,(linux shell查看进程号:ps -axj)正数:要接收的信号的进程的进程号;0:信号被发送到所有和pid进程在同一个进程组的进程;-1:信号发给所有的进程表中的进程(除了进程号最大的进程外)2)sig,信号(linux shell查看所有信号:kill -l)返回值:成功:0;失败:-1。
int rasie(int sig); -----> #include <signal.h>、#include <sys/types.h>参数:sig,信号;返回值:成功:0;出错:-1;发送信号给自己,相当于kill(getpid(), sig);注意:getpid() -->获取当前进程的进程号;getppid() -->获取当前进程的父进程的进程号。exit(0)  --->包含kill(getppid(), 17);
unsigned int alarm(unsigned int seconds);   ---->#include <unistd.h>功能:alarm只会发送SIGALARM信号,alarm会让内核定时一段时间之后发送信号,raise会让内核立刻发送信号。参数:seconds,秒数;返回值:成功:如果调用此alarm()之前,进程已经设置了闹钟时间,则返回上一个闹钟时间的剩余时       间,否则返回0;出错:-1;

下面是几种常见的信号:

      SIGHUP :从终端上发出的结束信号.SIGINT   :来自键盘的中断信号 ( ctrl + c ) .SIGKILL :该信号结束接收信号的进程 .SIGTERM:kill 命令发出 的信号.SIGCHLD:标识子进程停止或结束的信号.SIGSTOP:来自键盘 ( ctrl + z ) 或调试程序的停止执行信号.

2、信号的接收(接收信号进程)

 接收信号的进程,需要满足的条件为这个进程不能结束:sleep。pause():使进程处于睡眠状态(S)。
int pause(void); ------>#include <unistd.h>返回值:成功:0;出错:-1。

3、信号的处理(接收信号进程)

接收信号的进程,应该怎样处理?处理的方式:
1)进程的默认处理方式(内核为用户进程设置的默认处理方式)A.忽略B.终止进程C.暂停
2)自己的处理方式:自己告诉内核自己需要处理信号的方式。
void (*signal(int signum, void(*handler)(int)))(int); ----->#include <signal.h>参数:1)signum,指定信号,信号值;2)handler:SIG_IGN:忽略该信号;SIG_DFL:采用系统默认方式处理信号;自定义的信号处理函数指针;返回值:成功:设置之前的信号处理方式;出错:-1;

五、IPC通信

1、共享内存

打开或创建一个共享内存对象,共享内核在内核是什么样子?
一块缓存,变类似于用户空间的数组或malloc函数分配的空间一样。
所需头文件 #include <sys/types.h>、#include <sys/ipc.h>、#include <sys/shm.h>
函数原型 int shmget(key_t key, int size, int shmflg);
参数 key:IPC_PRIVATE或ftok的返回值;
size:共享内存区大小;
shmflg:同open函数的权限位,也可以用8进制表示法。
返回值 成功:共享内存段标识符–ID–文件描述符;出错:-1.
查看IPC对象:ipcs -m(共享内存) / -q(消息队列) / -s(信号灯);
删除IPC对象:ipcrm -m/-q/-s id;
ftok函数:创建key值。
char ftok(const char *path, char key);参数:1)文件路径和文件名;2)一个字符;返回值:成功:返回一个key值;出错:-1;IPC_PRIVATE操作时,共享内存的key值都一样,都是0,所以使用ftok来创建。

shmat 将共享内存映射到用户空间中,为了方便用户空间对共享内存的操作,使用地址映射的方式。

void *shmat(int shmid, const void *shmaddr, int shmflg);参数:1)shmid,ID号2)映射到的地址,NULL为系统自动完成的映射;3)shmflg, SHM_RDONLY共享内存只读默认是0,表示共享内存可读写。返回值:成功:映射后的地址;失败:NULL。
共享内存特点:1、共享内存创建之后,一直存在于内核中,直到被删除或系统关闭;2、共享内存和管道不一样,读取后,内容仍在共享内存中。
shmdt:将用户空间的进程里的地址映射删除。
int shmdt(const void *shmaddr);参数:shmaddr,共享内存映射后的地址返回值:成功:0;出错:-1.
shmctl:删除共享内存对象。
int shmctl(int shmid, int cmd, struct shmid_ds *buf);参数:1)shmid,要操作的共享内存标识符。2)cmd:  IPC_STAT(获取对象属性)   ---->实现了ipcs -m命令IPC_SET(设置对象属性)IPC_RMID(删除对象)   ---->实现了ipcrm -m命令3)buf:指定IPC_STAT/IPC_SET时用以保存或设置属性返回值:成功:0;出错:-1.

六、消息队列

msqid_ds 内核维护消息队列的结构体,队列的第一个消息指针msg_first,最后一个消息指针msg_last,消息中有一个成员指针next。
每一个消息中包含有哪些内容:
Data 数据
Length 数据的长度
Type 数据的类型

msgget  -----  消息队列的创建或打开函数
int msgget(key_t key, int flag);   ----> #include <sys/types.h>/#include <sys/ipc.h>/#include <sys/msg.h>参数:key,和消息队列关联的key值;(两种来源,同共享内存)flag,消息队列的访问权限;返回值:成功:消息队列的ID;出错:-1。
msgctl:删除消息队列对象。
int msgctl(int msgqid, int cmd, struct msgqid_ds *buf);参数:1)msgqid,消息队列的队列ID2)cmd:  IPC_STAT(获取消息队列属性,并将其保存在buf指向的缓冲区中)   ---->实现了ipcs -q命令IPC_SET(设置消息队列属性,这个值取自buf参数)IPC_RMID(删除消息队列)   ---->实现了ipcrm -q命令3)buf:消息队列缓冲区返回值:成功:0;出错:-1.
msgsnd   写消息队列
int msgsnd(int msgqid, const void *msgp, size_t size, int flag);参数:1)msqid:消息队列的ID;2)msgp:指向消息的指针。常用消息结构msgbuf如下:struct msgbuf{long mtype;    //消息类型char mtext[N]; //消息正文};3)size:发送的消息正文的字节数4)flag:IPC_NOWAIT  消息没有发送完成函数也会立即返回;0           直到发送完成函数才返回;返回值:成功:0;出错:-1.
msgrcv  读消息队列
int msgrcv(int msgid, void *msgp, size_t size, long magtype, int flag);参数:1)msgid:消息队列的ID2)msgp:接收消息的缓冲区3)size:要接收的消息的字节数4)msgtype:  0:接收消息队列中的第一个消息;>0:接收消息队列中第一个类型为msgtyp的消息;<0:接收消息队列中类型值不大于msgtyp的绝对值且类型值又最小的消息。5)flag:    0:若无消息会一直阻塞;IPC_NOWAIT:若没有消息,进程会立即返回ENOMSG.返回值:1)成功:接收到的消息的长度;2)出错:-1;

七、信号灯

所有的函数都是对一个集合的操作。
#include <sys/types.h>、#include <sy/sipc.h>、#include <sys/sem.h>

semget  --->创建/打开信号灯集
int semget(key_t key, int nsems, int semflg);参数: 1)key: 和信号灯集关联的key值;2)nsems: 信号灯集中包含的信号灯数目;3)semflg: 信号灯集的访问权限;返回值:1)成功:信号灯集的ID;2)出错:-1.
semctl  ---->删除信号灯集
int semctl(int semid, int semnum, int cmd, ...union semun arg(不是地址));参数:1)semid:信号灯集ID;2)semnum:要修改的信号灯变量(若要删除信号灯集,此参数可以随意选择)3)cmd:  GETVAL:获取信号灯的值;SETVAL:设置信号灯的值;IPC_RMID:从系统中删除信号灯集合.返回值:成功:0;出错:-1.

linux系统编程之进程通信相关推荐

  1. linux进程通信发送方式,Linux服务器编程——Linux系统编程之进程通信

    进程通信又称IPC IPC方法 方法:管道(最简单) 信号(开销最小) 共享映射区/共享内存(无血缘关系) 本地套接字(最稳定) Linux文件类型: -   文件 d  目录 l   符号链接 s  ...

  2. 【Linux系统编程】进程通信之管道

    1.进程间通信介绍 1.1 进程通信的基本概念 在之前我们已经学习过进程地址空间.Linux 环境下,进程地址空间相互独立,每个进程各自有不同的用户地址空间.任何一个进程的全局变量在另一个进程中都看不 ...

  3. Liunx系统编程篇—进程通信(五)信号

    Liunx系统编程篇-进程通信(五)信号 原理 对于Linux,信号是软中断,例如下课铃响了,老师要停止讲课.许多重要的程序都需要处理信号. 信号,为 Linux 提供了一种处理异步事件的方法.比如, ...

  4. vbs结束进程代码_物联网学习教程—Linux系统编程之进程控制

    Linux系统编程之进程控制 一.结束进程 首先,我们回顾一下 C 语言中 continue, break, return 的作用: continue: 结束本次循环 break: 跳出整个循环,或跳 ...

  5. Linux系统编程之进程与线程控制原语对比

    Linux系统编程之进程与线程控制原语对比 进程 线程 fork pthread_create exit pthread_exit wait pthread_join kill pthread_can ...

  6. 【Linux系统编程】进程替换:exec 函数族

    00. 目录 文章目录 00. 目录 01. exec函数族 02. 参考示例 2.1 execl函数示例 2.2 execv函数示例 2.3 execlp() 或 execvp()函数示例 2.4 ...

  7. 【Linux系统编程】进程概述和进程号

    00. 目录 文章目录 00. 目录 01. 进程概述 02. 进程状态 03. 进程控制块 04. 进程号 05. 进程号相关函数 06. 案例实战 07. 附录 01. 进程概述 我们平时写的 C ...

  8. linux系统编程之进程(八):守护进程详解及创建,daemon()使用

    linux系统编程之进程(八):守护进程详解及创建,daemon()使用 一,守护进程概述 Linux Daemon(守护进程)是运行在后台的一种特殊进程.它独立于控制终端并且周期性地执行某种任务或等 ...

  9. 【Linux系统编程】进程退出和回收进程资源

    00. 目录 文章目录 00. 目录 01. 进程退出函数 02. 进程退出讨论 03. 回收进程资源 04. 附录 01. 进程退出函数 #include <stdlib.h>void ...

  10. 【Linux系统编程】进程内存模型

    00. 目录 文章目录 00. 目录 01. Linux可执行程序结构 02. Linux进程结构 03. 存储类型总结 04. 附录 01. Linux可执行程序结构 在 Linux 下,程序是一个 ...

最新文章

  1. GPU — Overview
  2. 解决 IDEA 调用其他类的时候自动加上包路径和类名的情况_惊呆了!不改一行 Java 代码竟然就能轻松解决敏感信息加解密...
  3. 实验10 SQL Server 数据备份/恢复
  4. java 停止kettle转换_通过java运行Kettle转换
  5. vue 数值 拼接字符串_【Vue原理】Compile - 白话版
  6. dw 网页 html 布局,Dreamweaver网页制作之CSS布局规则
  7. ORACLE SEQUENCE用法 (自增长)
  8. HTML自动刷新页面
  9. python之爬虫学习记录与心得
  10. 沟通与设计讨论总结:设计师不能不知道的10个沟通秘诀
  11. linux上实现getch()函数
  12. c语言现代程序设计 现代方法_红河分局加强水文现代化新技术、新仪器、新方法的使用和创新...
  13. 足球机器人比赛3V3
  14. 数据库存储大文本类型
  15. 【中秋系列】这款秘制Python月饼游戏,拿走不谢~
  16. CPU通用寄存器 eax ebx ecx edx esp ebp esi edi
  17. python与历史专业_python历史与基本类型
  18. 《数据结构》-图的六度空间理论(二)
  19. sip pbx_PBX免费CRM
  20. python温度转换_一步一步教会你,详解用Python实现一个简易的温度换算GUI小工具...

热门文章

  1. 计算机桌面定制操作,教程方法;12、设置桌面--电脑基础知识电脑技巧-琪琪词资源网...
  2. 邮件营销EDM(Email Direct Marketing) 运营笔记
  3. Python崛金系列--4.python量化股票
  4. Protel DXP使用教程 -建立工程与绘制原理图PCB图
  5. 《眼儿媚·愁云淡淡雨潇潇》
  6. 性能测试——jmeter性能测试——重点—核心——线程组、Ramp-Up Period、Loop Count 次采样...
  7. 从3D打印到python编程 从opencv到人脸识别 从win10到树莓派ubuntu (全教程附代码)
  8. 嗯,春招两次腾讯面试都挂二面了,分享下我失败+傻傻的面试经历
  9. 【渗透测试笔记】之【钓鱼姿势——exe捆绑与免杀】
  10. 算法题目:小于n的最大数