一,Linux下进程间通信的几种主要手段简介:

1,管道(Pipe)及有名管道(named pipe)

管道可用于具有亲缘关系进程间的通信

有名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允许无亲缘关系进程间的通信;

2,信号(Signal):,

3,消息队列(Message):

消息队列是消息的链接表,包括Posix消息队列system V消息队列

消息队列克服了信号承载信息量少,管道只能承载无格式字节流以及缓冲区大小受限等缺点。

4,共享内存:

使得多个进程可以访问同一块内存空间,是最快的可用IPC形式。是针对其他通信机制运行效率较低而设计的。往往与其它通信机制,如信号量结合使用,来达到进程间的同步及互斥。

5,信号量(Semaphore):

主要作为进程间以及同一进程不同线程之间的同步手段。

6,套接口(Socket):更为一般的进程间通信机制,可用于不同机器之间的进程间通信。

二,管道

参考https://www.cnblogs.com/cfans1993/p/5657478.html

https://www.cnblogs.com/52php/p/5878029.html

https://www.cnblogs.com/52php/p/5840229.html

管道是Linux支持的最初Unix IPC形式之一,具有以下特点:

管道是半双工的,数据只能向一个方向流动;需要双方通信时,需要建立起两个管道;

只能用于父子进程或者兄弟进程之间(具有亲缘关系的进程);

单独构成一种独立的文件系统:管道对于管道两端的进程而言,就是一个文件,但它不是普通的文件,它不属于某种文件系统,而是自立门户,单独构成一种文件系统,并且只存在与内存中。

数据的读出和写入:一个进程向管道中写的内容被管道另一端的进程读出。写入的内容每次都添加在管道缓冲区的末尾,并且每次都是从缓冲区的头部读出数据。

2.1 pipe

#include

int pipe(int fd[2])

专用于父子进程通信, 函数原型 int pipe(int fd[2])

fd[0]表示输入, fd[1]表示输出

如果父子进程要双向通信, 可以通过类似信号的功能进行控制, 也可以简单地打开两个pipe

用read,Wright 读写

只有阻塞方式

当管道的写端存在时,数据不能超过PIPE_BUF 注:(不同系统要求的PIPE_BUF不一样,通常为512字节)。

2.2  popen和pclose

#include

FILE* popen(const char *command, const char *open_mode);

int pclose(FILE *stream_to_close);

函数原型FILE *popen(const char *cmdstring, const char *type) , type的参数为"r"或"w"

用于父子进程通信, popen会自动fork子进程、创建pipe和关闭不需要的pipe端

popen的实现有可理解为execl("/bin/sh","sh","-c",cmdstring,NULL)

当父进程向子进程发送信息时(type="w"), 实际就是向shell发送命令;

当父进程从子进程获取信息时(type="r"), 实际就是读取shell的执行结果

虽然popen的返回是FILE,但关闭是要用pclose(fp)

用fread 和fwright写

只有阻塞方式

#include

#include

#include

#define MAXLINE 1024

void err_quit(const char *str){

perror(str);

exit(1);

}

int main(){

char line[MAXLINE];

FILE *fpin;

if((fpin=popen("ls -l","r")) == NULL)

err_quit("popen error");

while(fgets(line,MAXLINE,fpin) != NULL){

if(fputs(line,stdout) ==EOF)

err_quit("fputs error");

}

if(ferror(fpin))

err_quit("fpin error");

if(pclose(fpin)==-1)

err_quit("pclose error");

return 0;

}

2.3 fifo

int mkfifo(const char *pathname,mode_t mode), 创建一个通信文件, 参数同open

mkfifo后, 以open打开文件pathname, 打开方式为只读或只写, 另外可以用阻塞或非阻塞方式打开

以只读打开时, 函数会阻塞直到有进程以只写方式打开

以只写打开时, 函数会阻塞直到有进程以只读方式打开

可用于非父子进程通信, 不同的进程只需要将pathname设置为同一文件,就可以通信。双向通信时开需两个

在一个进程中用mkfifo将一个文件设置为FIFO模式,同时open函数打开,read,Wright读写,另外一个进程只需要open和read,wright

三, 信号量

https://www.cnblogs.com/52php/p/5851570.html

3.1 信号量的工作原理

由于信号量只能进行两种操作等待和发送信号,即P(sv)和V(sv),他们的行为是这样的:

P(sv):如果sv的值大于零,就给它减1;如果它的值为零,就挂起该进程的执行

V(sv):如果有其他进程因等待sv而被挂起,就让它恢复运行,如果没有进程因等待sv而挂起,就给它加1.

举个例子,就是两个进程共享信号量sv,一旦其中一个进程执行了P(sv)操作,它将得到信号量,并可以进入临界区,使sv减1。而第二个进程将被阻止进入临界区,

因为当它试图执行P(sv)时,sv为0,它会被挂起以等待第一个进程离开临界区域并执行V(sv)释放信号量,这时第二个进程就可以恢复执行。

3.2、semget()函数

它的作用是创建一个新信号量或取得一个已有信号量,原型为:

int semget(key_t key, int num_sems, int sem_flags);

key是整数值(唯一非零),不相关的进程可以通过它访问一个信号量,比如每个进程都调用:

sem_id = semget((key_t) 1234, 1, 0666 | IPC_CREAT);就可以访问同一个信号量

3.3 semop()函数

它的作用是改变信号量的值,原型为:

int semop(int sem_id, struct sembuf *sem_opa, size_t num_sem_ops);

四,共享内存

参考:https://www.cnblogs.com/52php/p/5861372.html

4.1概念

不同进程之间共享的内存通常安排为同一段物理内存。通常与信号量一起用。

4.2 函数

int shmget(key_t key, size_t size, int shmflg);//不同的进程使用相同的key值,通常置为整形,就可以访问同一块共享内存

void *shmat(int shm_id, const void *shm_addr, int shmflg);  // attach启动对该共享内存的访问,可以用memcpy直接操作空间

int shmdt(const void *shmaddr);  //detach 该函数用于将共享内存从当前进程中分离。注意,将共享内存分离并不是删除它,只是使该共享内存对当前进程不再可用。

int shmctl(int shm_id, int command, struct shmid_ds *buf);  //用来控制共享内存

五,消息队列

5.1 概念

消息队列提供了一种从一个进程向另一个进程发送一个数据块的方法。 消息队列与命名管道一样,每个发送的数据块都有最大长度的限制。Linux用宏MSGMAX和MSGMNB来限制一条消息的最大长度和一个队列的最大长度。

5.2 函数

int msgget(key_t, key, int msgflg);//创建和访问消息队列

int msgsend(int msgid, const void *msg_ptr, size_t msg_sz, int msgflg);//把消息添加到消息队列中

int msgrcv(int msgid, void *msg_ptr, size_t msg_st, long int msgtype, int msgflg);//从一个消息队列获取消息

int msgctl(int msgid, int command, struct msgid_ds *buf);//控制消息队列

六,socket

https://www.cnblogs.com/52php/p/5872596.html

6.1 概念

套接字的特性由3个属性确定,它们分别是:域、类型和协议。

套接字的域:

AF_INET,它指的是Internet网络

AF_UNIX表示UNIX文件系统,它就是文件输入/输出,而它的地址就是文件名。

套接字类型

流套接字 SOCK_STREAM: TCP

数据报套接字SOCK_DGRAM :UDP

6.2 套接字地址

不同的域,有不同的套接字地址格式

对于AF_UNIX域套接字来说,它的地址由结构sockaddr_un来描述,该结构定义在头文件sys/un.h中,它的定义如下:

1

2

3

4

struct sockaddr_un {

sa_family_t sun_family;// AF_UNIX,它是一个短整型

char        sum_path[];// 路径名

};

对于AF_INET域套接字来说,它的地址结构由sockaddr_in来描述,它至少包括以下几个成员:

1

2

3

4

5

struct sockaddr_in {

short int            sin_family;//AF_INET

unsignedshort int    sin_port;//端口号

struct in_addr        sin_addr;//IP地址

};

6.3 基于流套接字(tcp)的客户/服务器的工作流程

6.3.1 服务器

socket-》bind-》listen-》accept

6.3.1 客户端

socket-》connect

6.4 基于流套接字(tcp)的客户/服务器的工作流程

6.4.1 服务器

socket-》bind-》recvfrom/sendto

6.4.1 客户端

socket-》recvfrom/sendto

七,信号

https://www.cnblogs.com/52php/p/5813867.html

信号的名称是在头文件signal.h中定义的,信号都以SIG开头,常用的信号并不多,常用的信号如下:

更多的信号类型可查看附录表。

标签:信号量,int,管道,sv,间通信,Unix,Linux,进程,接字

来源: https://www.cnblogs.com/shelley-AL/p/10717714.html

linux msgsend 头文件,Unix/Linux进程间通信相关推荐

  1. 如何下载linux内核头文件,在Linux系统上安装Linux内核头文件的教程

    当你在编译一个设备驱动模块时,你需要在系统中安装内核头文件.内核头文件同样在你编译与内核直接链接的用户空间程序时需要.当你在这些情况下安装内核头文件时,你必须确保内核头文件精确地与你当前内核版本匹配( ...

  2. linux c之c语言符合标准的头文件和linux常用头文件

    1.C语言符合标准的头文件 #include <assert.h> //设定插入点 #include <ctype.h> //字符处理 #include <errno.h ...

  3. linux语言的说明顺序有哪些,(linux常用头文件详解.doc

    (linux常用头文件详解 linux常用头文件详解 POSIX标准定义的头文件??????? 目录项 ???????? 文件控制 ??? 文件名匹配类型 ??? 路径名模式匹配类型 ??????? ...

  4. linux 常用头文件,(常用头文件详解.doc

    (常用头文件详解 linux常用头文件详解 POSIX标准定义的头文件??????? 目录项 ???????? 文件控制 ??? 文件名匹配类型 ??? 路径名模式匹配类型 ??????? 组文件 ? ...

  5. Linux C try 头文件,linux c 头文件

    //1.Linux中一些头文件的作用: #include //ANSI C.提供断言,assert(表达式) #include //GCC.GTK,GNOME的基础库,提供很多有用的函数,如有数据结构 ...

  6. linux的头文件下载,Linux内核头文件(linux headers)

    更新 Linux 内核头文件(linux headers) 三 8th, 2013 2,474 views | 发表评论 | Trackback 一般来说,如果不是自己编译 kernel,那么更新头文 ...

  7. 如何向linux中添加头文件,linux添加头文件路径

    gcc demo.c -o demo  -I/tools/libevent/include -L/tools/libevent/lib -levent -I:头文件目录 -L:静态库目录 -l:静态库 ...

  8. Linux之头文件引用小技巧(二十九)

    Linux之头文件引用小技巧 0.需求: 将本地头文件引用,#include "test.h"更换为#include <test.h>系统引用方式.1.目录结构如下├─ ...

  9. #include sys/xxx.h头文件 UNIX头文件

    原文地址:#include sys/xxx.h头文件 UNIX头文件 作者:embededgood #include sys/xxx.h是Linux系统中的系统头文件 应用程序的头文件在/usr/in ...

最新文章

  1. 阿里三面让我现场改造Spring框架,明天带他去爬山!
  2. debian php redis,debian7.7环境下 源码安装redis以及phpredis扩展
  3. dedecms直接访问域名不能跳转到index.php怎么办
  4. python代码检查工具_基于Python3的漏洞检测工具 ( Python3 插件式框架 )
  5. Mysql中的in和find_in_set的区别?
  6. java学习(73):GUL网格布局管理器
  7. android(安卓)手机 markdown不错的编辑器
  8. android 7.0 自启管理,一款不错的android6.0、7.0权限管理器推荐
  9. jsp页面将数据导出到Excel
  10. 前端开发 —— js 常用工具函数(utilities)
  11. 用firework中合并图标的方法
  12. php mktime 2037,phpmktime计算两时间之差_PHP教程
  13. Python中的时间序列数据可视化的完整指南
  14. MySQL学习2:表的创建和增删改
  15. 投影仪的对比度多少合适,当贝X3高亮对比度和电视基本一样
  16. 使用flink迁移数据
  17. iOS 提取图片中的文字
  18. 7 netsnmp安装window_NET SNMP|NET-SNMP windows版下载 v5.6.1.1 32位版 - 121下载站
  19. day-17正则表达式
  20. 青云算法面试题干货-开密码锁-LeetCode第752题

热门文章

  1. Orchard是如何工作的?
  2. DispatcherServlet与初始化主线
  3. 【No.4 Ionic】修改 cordova 插件
  4. python 如何加密自己的脚本
  5. Eclipse搭建SSH环境实现Struts2分页显示mysql数据库表中内容
  6. Markdown 调整图片位置与大小
  7. C++ 名字空间详解
  8. Java中使用MongoTemplate写聚合函数样例
  9. Jmeter 常用断言使用
  10. shell命令xargs