LINUX系统编程之IPC

LINUX系统编程之IPC(Inter Processes Communication)

一、信号

1.信号的产生

软件中断,异步通信,ctrl+c,kill函数,kill命令,硬件异常(段错误),软件异常

2.进程收到信号后可以用如下方法处理:

执行系统默认动作(终止),忽略此信号,执行自定义信号处理函数。

3.信号操作函数

kill(), alarm(), raise(), abort(), pause()

typedef void (*sighandler_t)(int);signal()

sigemptyset(), sigfillset(), sigismember(), sigdelset(), sigaddset()....

信号阻塞集:阻塞信号的接收sigprocmask();

二、管道/命名管道

1.无名管道:类似于一个文件,有2个文件描述符,只存在于内存

半双工,数据从写端入,读端出,先入先出,fd[0]输出,fd[1]写入

数据无格式要求,只固定大小,没有名字,用fork和vfork会继承其描述符

只有公共祖先进程使用,如父进程创建的管道只有该父进程和其子进程能访问

int fd[2];

pipe(fd);

write();read();

close(fd);

read从管道中读取数据时会阻塞,有数据就读到返回,没数据则等待,

write从管道写数据,写满阻塞,直到数据被读出

如果读进程退出了,写进程写数据时也会退出可用fcntl()设置阻塞特性

dup(old)复制old文件描述符并分配一个新的描述符,读写位置也会复制

dup2(old, new)复制文件描述符old,分配新的文件描述符new, new也标识old所标识的文件

常用如重定向0,1,2描述符

int fd_stdout=dup(1);复制stdout描述符1

dup2(fd_stdout, 1);将描述符1重新分配给stdout

2.命名管道FIFO

有名字,存在于文件系统,内容只存在于内存

不相关的进程也能使用

命名管道复制后会变成普通文件

mkfifo("./cmd_fifo", 0777);

open("./cmd_fifo", O_RDWR);

write();read();

close();

3.消息队列

由内核维护的链表,消息有格式(结构体),消息有类型,可按照类型随机查询

有标识符,只有内核重启或人工删除才能删除

结构体第一个成员代表消息类型必须是long型变量,其它自行定义

发送消息msgsent(msqid, &msg, sizeof(msg)-4, 0);

接收消息msgrcv(msqid, &msg, sizeof(msg)-4, type, 0);返回长度

控制msgctl(msgqid, IPC_RMID, NULL)

typedef struct _msg

{

long mtype;

char mtext[50];

}MSG;

MSG msg;

key=ftok(".", 2012)

msgqid = msgget(key, IPC_CREAT|0666);

if(msgqid==-1)

perror("msgget");

msgrcv(msgqid, &msg, sizeof(msg.mtext), 10, 0);

msgctl(msgqid, IPC_RMID, NULL);

查看消息队列ipcs -q

删除消息队列ipcrm -q msgqid

4.共享内存

多个进程共享给定的存储空间

最快的通信方式,访问互斥

查看ipcs -m

删除ipcrm -m shmid

创建或打开int shmid = shmget(key, size, flag);

内存映射shmat()

解除映射shmdt()

控制shmctl()

原文地址:http://blog.51cto.com/13603157/2105979

时间: 2024-10-06 05:08:49

LINUX系统编程之IPC的相关文章

linux系统编程之lseek帮助文档

通过man 2 lseek可以查看linux中的系统函数lseek函数的帮助文档,为了更好的学习,我把这些重要内容翻译过来 1 NAME 2 lseek - reposition read/write file offset//重置读或写文件的偏移量 3 4 SYNOPSIS//摘要 5 #include <sys/types.h>//如果要使用lseek函数,需要包含这两个头文件 6 #include <unistd.h> 7 8 off_t lseek(int fd, off_

linux系统编程之I/O内核数据结构

文件在内核中是用三种数据结构进行表示的 (1)文件描述符表:文件描述符表是一个结构体数组,数组的下标就是open函数返回的文件描述符. 文件描述符表的每一个记录有两个字段   *文件描述符标志 * 文件表项指针 (2)文件表项:一般含有一下内容 * 文件状体标志,读,写,追加,同步,阻塞,非阻塞等 * 当前文件偏移量 * i节点指针 * 引用计数 (3)i节点:一般含有一下记录 * 文件类型 * 对该文件的操作函数的指针 * 当前文件的长度 *文件的所有者 * 文件的权限 * 指向文件数据在磁盘

Linux系统编程之IO_缓冲和非缓冲

下面是一段类似日志记录的代码,已获取通讯的报文内容和当时的环境参数内容,就是创建一个文件,使用标准IO的fopen.fprintf进行输出记录.但是在调试中,刚开始我就傻眼了,文件创建成功了,但是实时查看竟然没有任何数据记录.经过半天的担惊受怕和反复排查,发现是被标准IO的缓冲机制摆了一道,惭愧呀... 代码转自http://blog.csdn.net/mr_chenping/article/details/9166937 下面给出一个示例程序,模拟我的项目程序: #include <stdio

Linux环境编程之IPC进程间通信(五):Posix消息队列1

对于管道和FIFO来说,必须应该先有读取者存在,否则先有写入者是没有意义的.而消息队列则不同,它是一个消息链表,有足够写权限的线程可往别的队列中放置消息,有足够读权限的线程可从队列中取走消息.每个消息都是一个记录,它由发送者赋予一个优先级.在某个进程往一个队列写入消息之前,并不需要另外某个进程在该队列上等待消息的到达.消息队列是随内核的持续性,一个进程可以往某个队列写入一些消息,然后终止,再让另外一个进程在以后的某个时刻读出这些消息.这跟管道和FIFO不一样,当一个管道或FIFO的最后一次关闭时

Linux环境编程之IPC进程间通信(三):FIFO

管道是没有名字的,因此它只能在有亲缘关系的进程间使用,给管道加上名字,我们称之为有名管道FIFO,当然FIFO与管道之间不止有没有名字的区别,还有其他区别下面会提到.与管道类似的是,FIFO是一个单向(半双工)数据流.不同于管道的是,每个FIFO有一个路径名与之关联,从而允许无亲缘关系的进程之间访问同一个FIFO.FIFO是一种文件类型.stat结构成员st_mode的编码指明文件是否是FIFO类型,可以用S_ISFIFO宏对此进行测试. FIFO由mkfifo函数创建,它已经隐含指定了O_CR

Linux环境编程之IPC进程间通信(四):管道和FIFO比较

系统加于管道和FIFO的唯一限制是: 1.OPEN_MAX 一个进程在任意时刻打开的最大描述符数.可以通过调用sysconf函数查询. 2.PIPE_BUF 可原子地写往一个管道或FIFO的最大数据量.Posix任务它是一个路径名变量,它的值可以随指定的路径名而变化,因为不同的路径名可以落在不同文件系统上,而这些文件系统可能有不同的特征.所以PIPE_BUF可通过pathconf函数取得. pipeconf.c #include <stdio.h> #include <stdlib.h&

Linux环境编程之IPC进程间通信(二):管道

管道作为最古老的进程间通信方法,它有以下几个特点: 1.在所有的UNIX实现中都存在. 2.没有名字,因此只能由有亲缘关系的进程使用. 3.它由函数pipe创建,read和write函数访问,但只提供单路(单向)数据流. <span style="font-size:14px;">#include <unistd.h> int pipe(int fd[2]); 返回:若成功则为0,若出错则为-1</span> 经由参数fd返回两个文件描述符:fd[0

Linux系统启动流程之(3)系统故障修复之二

Linux系统启动流程之(3)系统故障修复之二 通过上一篇可以了解如何来重新安装grub从而修复grub引导,那么如果损坏的不仅仅为grub引导,如果还出现了其它更为严重的问题呢.下面几个案例来说明: 案例一: 通常系统服务运行之前会运行init程序来开启第一个进程,那么如果init被删除呢? #删除或者移动init程序到别处 [[email protected] ~]# which init /sbin/init [[email protected] ~]# mv /sbin/init /te

linux网络编程之shutdown() 与 close()函数详解

linux网络编程之shutdown() 与 close()函数详解 参考TCPIP网络编程和UNP: shutdown函数不能关闭套接字,只能关闭输入和输出流,然后发送EOF,假设套接字为A,那么这个函数会关闭所有和A相关的套接字,包括复制的:而close能直接关闭套接字. 1.close()函数 [cpp] view plain copy print? <span style="font-size:13px;">#include<unistd.h> int