黑马程序员C语言教程:Linu 常见的六大IPC 通信方式

上传人:m**** 文档编号:552700327 上传时间:2023-09-01 格式:DOCX 页数:9 大小:31.64KB
返回 下载 相关 举报
黑马程序员C语言教程:Linu 常见的六大IPC 通信方式_第1页
第1页 / 共9页
黑马程序员C语言教程:Linu 常见的六大IPC 通信方式_第2页
第2页 / 共9页
黑马程序员C语言教程:Linu 常见的六大IPC 通信方式_第3页
第3页 / 共9页
黑马程序员C语言教程:Linu 常见的六大IPC 通信方式_第4页
第4页 / 共9页
黑马程序员C语言教程:Linu 常见的六大IPC 通信方式_第5页
第5页 / 共9页
点击查看更多>>
资源描述

《黑马程序员C语言教程:Linu 常见的六大IPC 通信方式》由会员分享,可在线阅读,更多相关《黑马程序员C语言教程:Linu 常见的六大IPC 通信方式(9页珍藏版)》请在金锄头文库上搜索。

1、www.ittiefrna.conn SSSSeits改变中国IT数育,理们证在抒动传智播客C/C+培训专家Linux 常见的六大 IPC 通信方式Linux环境下,进程地址空间相互独立,每个进程各自有不同的用户地址空间。 任何一个进程的全局变量在另一个进程中都看不到,所以进程和进程之间不能相 互访问,要交换数据必须通过内核,在内核中开辟一块缓冲区,进程1把数据从 用户空间拷到内核缓冲区,进程2再从内核缓冲区把数据读走,内核提供的这种 机制称为进程间通信(IPC, InterProcess Communication)。今天我们来看一下,Linux 下常见的六大IPC通信方式。1、信号信号是U

2、nix/Linux系统在一定条件下生成的事件。信号是一种异步通信机制,进程不需 要执行任何操作来等待信号的到达。信号异步通知接收信号的进程发生了某个事件,然后操 作系统将会中断接收到信号的进程的执行,转而去执行相应的信号处理程序。(1) 注册信号处理函数#in elude vsig nal.h/*typedef void (*sighandler_t)(int); sighandler_t signal(int signum,sighandler_than dler);*/void (*sig nal(i nt sig num, void (*ha ndler)(i nt)(i nt); SI

3、G_IGN & SIG_DFLint sigacti on (i nt sig num, const struct sigacti on *act,struct sigacti on *oldact);(2 )发送信号#in clude int kill(pid_t pid,i nt sig);/# in clude in t raise(i nt sig);kill(getpid(),sig);un sig ned int alarm( un sig ned int sec on ds);/(# in clude vuni std.h) sec onds 秒后,向 进程本身发送SIGALRM

4、信号。(3)信号集信号集被定义为:typedef struct un sig ned long sig_NSIG_WORDS; sigset_t;* int sigaddset(sigset_t *set,i nt sig);* int sigemptyset(sigset_t *set);鶴聲播舂坯下 高站iTii育品牌2、管道(Pipe)管道用来连接不同进程之间的数据流。在两个程序之间传递数据的最简单的方法是使用popen()和pclose()函数:#i nclude vstdio.hFILE *pope n(const char *comma nd, const char *ope n_

5、mode);int pclose(FILE *stream);popen()函数首先调用一个shell,然后把command作为参数传递给shell。这样每次调 用popen()函数都需要启动两个进程;但是由于在Linux中,所有的参数扩展(parameter expansion)都是由shell执行的,这样command中包含的所有参数扩展都可以在command 程序启动之前完成。(2) pipe ()函数:int pipe(i nt pipefd2);popen()函数只能返回一个管道描述符,并且返回的是文件流(file stream),可以使用函 数fread()和fwrite()来访问

6、。pipe()函数可以返回两个管道描述符:pipefd0和pipefd1,任 何写入p/pefd1的数据都可以从p/pefd0读回;pipe()函数返回的是文件描述符(file descriptor),因此只能使用底层的read()和write()系统调用来访问。pipe()函数通常用来实 现父子进程之间的通信。(3) 命名管道:FIFOint mkfifo(c onst char *fifo_ name, mode_t mode);前面两种管道只能用在相关的程序之间,使用命名管道可以解决这个问题。在使用open() 打开FIFO时,mode中不能包含O_RDWR。mode最常用的是O_RDO

7、NLY, O_WRONLY 与O_NONBLOCK的组合。O_NONBLOCK影响了 read()和write()在FIFO上的执行方式。3、信号量(Semaphores)System V的信号量集表示的是一个或多个信号量的集合。内核为每个信号量集维护一个 semid_ds数据结构,而信号量集中的每个信号量使用一个无名结构体表示,这个结构体至 少包含以下成员:structun sig ned short semval;/信 号量值,总是 =0pid_t sempid; 上一次操作的 pid ;(1)创建或访问信号量int semget(key_t key,i nt n sems,i nt fl

8、ag);nsems指定信号量集中信号量的个数,如果只是获取信号量集的标识符(而非新建),那 么nsems可以为0。flag的低9位作为信号量的访问权限位,类似于文件的访问权限如果 flag中同时指定了 IPC_CREAT和IPC_EXCL,那么如果key已与现存IPC对象想关联的 话,函数将会返回EEXIST错误。例如,flag可以为IPC_CREAT|0666。(2) 控制信号量集int semctl(i nt semid,i nt sem num,i nt cmd, union sem un arg);对semid信号量集合执行cmd操作;cmd常用的两个值是:SETVAL初始化第sem

9、num个 信号量的值为arg.val;IPC_RMID删除信号量。(3) 对一个或多个信号量进行操作int semop(i nt semid,struct sembuf *sops, un sig ned n sops);struct sembufunsigned short sem_num; 信号量索弓Ishort sem_op; 对信号量进行的操作,常用的两个值为-1和+1,分别代表P、 V操作short sem_flag; 比较重要的值是SEM_UNDO:当进程结束时,相应的操作 将被取消;同时,如果进程结束时没有释放资源的话,系统会自动释放;4、共享内存共享内存允许两个或多个进程共享一

10、定的存储区,因为不需要拷贝数据,所以这是最快 的一种IPC。(1) 创建或访问共享内存int shmget(key_t key,size_t size,i nt shmflg);(2) 附加共享内存到进程的地址空间void *shmat(int shmid,const void *shmaddr,int shmflg)/shmaddr 通常为 NULL,由系 统选择共享内存附加的地址;shmflg可以为SHM_RDONLY(3) 从进程的地址空间分离共享内存* int shmdt(co nst void *shmaddr); /shmaddr 是 shmat ()函数的返回值(4) 控制共享内

11、存int shmctl(i nt shmid,i nt cmd,struct shmid_ds *buf);struct shmid_dsstruct ipc_perm shm_perm;cmd的常用取值有:(a)IPC_STAT获取当前共享内存的shmid_ds结构并保存在buf中 (2)IPC_SET使用buf中的值设置当前共享内存的shmid_ds结构(3)IPC_RMID删除当前共 享内存5、消息队列消息队列保存在内核中,是一个由消息组成的链表。(1)创建或访问消息队列int msgget(key_t key,i nt msgflg);(2) 操作消息队列int msgs nd(i n

12、t msqid,c onst void *msg,size_t n bytes,i nt msgflg);msg指向的结构体必须以一个long int成员开头,作为msgrcv()的消息类型,必须大于0。nbytes指的是msg指向结构体的大小,但不包括long int部分的大小ssize_t msgrcv(i nt msqid,void *msg,size_t n bytes,l ong msgtype,i nt msgflg);如果msgtype是0,就返回消息队列中的第一个消息;如果是正整数,就返回队列中的第 一个该类型的消息;如果是负数,就返回队列中具有最小值的第一个消息,并且该最小值

13、要 小于等于msgtype的绝对值。(3) 控制消息队列int msgctl(i nt msqid,i nt cmd,struct msqid_ds *buf);struct msqid_dsstruct ipc_perm msg_perm;6、Socket套接字(Socket)是由Berkeley在BSD系统中引入的一种基于连接的IPC,是对网络 接口(硬件)和网络协议(软件)的抽象。它既解决了无名管道只能在相关进程间单 向通信的问题,又解决了网络上不同主机之间无法通信的问题。套接字有三个属性:域(domain)、类型(type)和协议(protocol),对应于不同的 域,套接字还有一个地

14、址(address)来作为它的名字。域(domain)指定了套接字通信所用到的协议族,最常用的域是AF_INET,代 表网络套接字,底层协议是 IP 协议。对于网络套接字,由于服务器端有可能会高站IT教育品牌改变中国IT教育,找们正在冇动提供多种服务,客户端需要使用IP端口号来指定特定的服务。AF_UNIX代表本 地套接字,使用 Unix/Linux 文件系统实现。IP协议提供了两种通信手段:流(streams)和数据报(datagrams),对应的套接字 类型(type)分别为流式套接字和数据报套接字。流式套接字(SOCK_STREAM)用于提 供面向连接、可靠的数据传输服务。该服务保证数据

15、能够实现无差错、无重复发 送,并按顺序接收。流式套接字使用TCP协议。数据报套接字(SOCK_DGRAM)提 供了一种无连接的服务。该服务并不能保证数据传输的可靠性,数据有可能在传 输过程中丢失或出现数据重复,且无法保证顺序地接收到数据。数据报套接字使 用 UDP 协议。一种类型的套接字可能可以使用多于一种的协议来实现,套接字的协议 (protocol)属性用于指定一种特定的协议。(1) 创建套接字int socket(int domain,int type,int protocol);对于SOCK_STREAM和SOCK_DGRAM而言,分别只有一种协议支持这种类型的套 接字。因此protocol可以为0,表示默认的协议。(2) 绑定套接字int bind(int sockfd,const struct sockaddr *addr,socklen_t addrlen) ; /将无名套接字sockfd 与 addr 绑定 (bind)(3) 监听套接字int listen (int sockfd, int backlog) ; /backlog 限定了等待服务 的队列的最大长度(4) 等待接受连接int acc

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 建筑/环境 > 建筑资料

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号