10.进程通信

进程间通信方式
1、管道 :将一个程序的输出直接连接到另一个程序的输入
无名管道:
    1、只能用在具有亲缘关系的进程
    2、半双工通信、pfd[0]只能用于读管道,pfd[1]只能用于写管道
    3、可以使用read、write;不要使用lseek,open
pipe(pfd[2]);//传参是数组的复制传参方式,实际上这里的pfd还是一个变量
有名管道:单独执行写端或者读端都会产生阻塞
    1、用于非亲缘关系进程
    2、半双工通信
    3、可以使用open、read、write函数,不能使用lseek
    注意:有名管道文件是linux环境下的文件类型。它只是用来索引内核空间,不能使用vi来直接操作有名管道文件
    单独执行写端或者读端都会产生阻塞
管道创建函数: int pipe( int fd[] )   fd[]为包含两个元素的整型数组,存放管道对应的文件描述符     头文件 unistd.h
2、信号 :是在软件层次上对中断机制的一种模拟,也是进程间通信机制中唯一的的异步通信
信号产生:硬件产生、函数产生
信号注册:信号值为1-31 叫做不可靠信号,信号值为34-64 叫做可靠信号,所谓的可靠指的是信号不能丢失
消亡并且执行:无论可靠还是不可靠信号只要执行过相应的信号就被被释放掉
信号的执行方式:捕捉、忽略、缺省操作(执行信号的默认操作)
kill -l
信号函数:
signal(int signum,sighandler_t hander):指定信号类型和信号处理函数,主要用于前32种非实时信号的处理
signum:指定信号代码    handler:1)SIG_IGN忽略该信号   2)SIG_DFL采用系统默认方式处理信号     3)传自定义的信号处理函数
int kill(pid_t pid,int sig):用来发送信号     pid:进程id   sig:信号类型
unsigned int alarm (unsigned int seconds):此函数在进程中设置一个定时器。当定时器的时间到时,它就向进程发送SIGALARM信号       seconds:指定秒数
3、 共享内存 是一种最为高效的进程间通信方式, 进程间通信(IPC)包括3种机制:消息队列、信号量、共享内存。消息队列和信号量均是内核空间的系统对象,经由它们的数据需要在内核和用户空间进行额外的数据拷贝;而共享内存和访问它的所有应用程序均同处于用户空间,应用进程可以通过地址映射的方式直接读写内存,从而获得非常高的通信效率。
系统建立IPC通讯( 消息队列,信号量和共享内存) 时必须指定一个ID值。通常情况下,该id值通过ftok函数得到。
建立共享内存函数
1) key_t ftok( char * fname, int id ): 指定ID     fname:指定的文件名(已经存在的文件名),一般使用当前目录   id:子序号   返回值:key              作用:生成key值,多个进程可以通过它来访问同一个共享内存
2)int shmget(key_t key,int size,int shmflg): 创建共享内存    key:ftok函数的返回值    size:共享内存区大小  shmflg:同open函数的权限位(O_改为IPC_ ),也可用八位进制表示法    返回值:共享内存段标识符
3)void *shmat(int shmd,const void *shmaddr,int shmflg): 映射共享内存     shmid:要映射的共享内存区标识符     shmaddr:将共享内存区映射到指定地址      shmflg:1)SHM_RDONLY共享内存只读        2)0:共享内存可读写   返回值:被映射的段地址
查看共享内存是否创建指令:ipcs      删除共享内存:ipcrm _m   id值
4)int shmdt(const void *shmaddr):          shmaddr:指shmat产生的映射地址
5)int shmctl(int shmid,int cmd,struct shmid_ds *buf): shmid共享内存区标识符      cmd:IPC_EMID删除这片共享内存                buf:一般写NULL
4、 消息队列: 消息队列就是一个消息的链表。可以把消息看作一个记录,具有特定的格式以及特定的优先级。对消息队列有写权限的进程可以向消息队列中按照一定的规则添加新消息;对消息队列有读权限的进程则可以从消息队列中读走消息。消息队列是随内核持续的。
消息队列的使用步骤
1)创建或打开消息队列
int msgget(key_t key,int msgflg) :key键值         msgflg权限标志位          返回值:成功返回消息队列ID,出错返回-1
2)发送消息
int msgsnd(int msgid,const void *msgp,size_t msgsz,int msgflg) :msgid消息队列ID     msgsz消息正文字节数   
msgp指向消息结构的指针,消息结构如下:
struct msgbuf{
    long mtype;   消息类型
    char mtext[1]; 消息正文
}
msgflg:为0表示调用阻塞直到发送成功         IPC_NOWAIT若消息无法立即发送 (比如消息队列已满) 函数会立即返回
3)接收消息
int msgrcv(int msgid,void *msgp,size_t msgsz,long int msgtyp,int msgflg):msgid消息队列ID    msgp指向消息结构的指针
msgsz消息正文字节数            msgtyp:为0表示接收消息队列中第一个消息                      msgflg同函数msgsnd()
4)控制消息队列
int msgctl(int msgid,int cmd,struct msqid_ds *buf):msgid消息队列ID     cmd:命令参数为IPC_RMID表示删除msqid_ds结构类型变量
       











猜你喜欢

转载自blog.csdn.net/qq_33575901/article/details/80958363
10.