一、信号管理

1、函数signal

signal函数是UNIX系统信号机制最简单的接口

#include <signal.h>

typedef void (*sighandler_t)(int);

sighandler_t signal(int signum, sighandler_t  handler );
/*
signum:信号的编号
handler: 函数指针 接到此信号时要调用的程序
SIG_IGN 忽略signum信号
SIG_DFL 恢复信号默认的处理方式 返回值:信号设置之前信号的处理方式
函数指针、SIG_IGN、SIG_DFL
*/

该函数用于设置一个指定信号的处理方式,可以一个自定义的指定类型函数,也可以选择忽略信号或恢复信号默认处理方式

2、函数kill

#include <sys/types.h>
#include <signal.h> int kill(pid_t pid, int sig);
// 功能:向指定的进程发送信号
// pid:与waitpid一样
// sig:信号码
// 0 空信号,不会向进程发送信号,但是会测试是否能向pid发送信号,可以检测一个进程是否存在,返回-1 表示进程不存在,errno变为ESRCH。
// 返回值:-1 说明进程不存在

该函数用于进程之间发送信号,可以在进程间通信使用共享内存时,用于发送读完毕或写完毕信号避免多进程同时访问同一块内存造成错误

二、进程间通信

1、共享内存

  1、由内核维护一块共享的内存区域,其它进程,把自己的虚拟地址映射到这块内存,多个进程之间就可以共享这块内存了。
  2、这种进程间通信的好处是不需要信息复制,它是进程间通信最快的一种方式。
  3、但这种通信方式会面临同步的问题,需要与其它通信方式配合,最合适的就是信号。

进程之间互相约定一个key值,此key值将会作为内核定位同一块内存的依据,使得多个进程之间能够共享一块内存

#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h> int shmget(key_t key, size_t size, int shmflg);/*
功能:创建共享内存
size:共享的大小
shmflg:IPC_CREAT:创建
IPC_EXCL :如果存在创建失败
IPC_EXCL | IPC_CREAT
mode_flags 权限
返回值:IPC对象标识符(类似文件描述符)
shmget(key,size,0744|IPC_CREAT);*/ void *shmat(int shmid, const void *shmaddr, int shmflg); /*
功能:加载共享内存(进程的虚拟地址和共享的内存进行映射)
shmid:shmget的返回值
shmaddr:进程提供的虚拟地址,如果为 NULL 操作系统会自动选择一块地址映射
shmflg: SHM_RDONLY: 限制内存的权限为只读
SHM_REMAP: 映射已经存在的共享内存
SHM_RND: 当shmaddr为NULL时自动分配
SHMLBA : shmaddr值不能为空,否则出错
返回值:映射后的虚拟地址
*/
int shmdt(const void *shmaddr);/*
功能:卸载共享内存(进程的虚拟地址与共享内存取消映射关系)*/ int shmctl(int shmid, int cmd, struct shmid_ds *buf);/*
共享:控制/销毁共享内存
cmd:
IPC_STAT:获取共享内存的属性
IPC_SET :设置共享内存的属性
IPC_RMID:删除共享内存
buf:记录共享内存属性的对象*/

共享内存一旦创建,系统上的进程只要拥有它的key值就能够通过函数shmget,shmat访问到该内存。

共享内存操作麻烦,需要配合信号使用,但共享内存更适合于较大的数据通信。

1、消息队列

1、消息队列是一个由系统内核负责存储和管理、并通过IPC对象标识符获取的数据链表。

2、使用消息队列需要创建一个定义了消息类型和消息大小的结构体,例:

struct msgbuf
{
long mtype; /*消息的类型,必须大于0 */
char mtext[]; /* 传输的数据 */
};

以下几个是于消息队列有关的函数:

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h> int msgget(key_t key, int msgflg);/*
功能:创建或获取消息队列
msgflg: 创建时 IPC_CREAT | IPC_EXCL | 0751(权限)
获取时 0
*/
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);/*
功能:向消息队列发送消息
msqid:msgget的返回值
msgp: 消息(消息类型+消息的内容)的首地址,如上的结构体
msgsz:消息内容的长度(不包括消息类型)
msgflg:
MSG_NOERROR: 当消息的实际长度比msgsz还要大,不产生错误,把消息按照长度截取发送*/ ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);/*
功能:从消息队列接收消息
msgp:存储消息的缓冲区
msgsz:要接收的消息长度
msgtyp:消息的类型(它包含在消息的前四个字节)
msgflg
IPC_NOWAIT:如果要接收的消息不存在,则不等待
MSG_EXCEPT:从消息队列中接收第一个不是msgtype类型的第一个消息。*/ int msgctl(int msqid, int cmd, struct msqid_ds *buf);/*
功能:控制/销毁消息队列
cmd: IPC_STAT:获取消息队列的属性
IPC_SET:设置消息队列的属性
IPC_RMID:删除消息队列*/

UNIX环境C语言进程通信的更多相关文章

  1. UNIX环境C语言进程控制

    一.进程ID 进程ID即是进程标识,每一个进程都会有一个唯一的非负整数来作为它的进程ID. ID为0的进程通常是调度进程,也可称为交换进程,该进程是内核的一部分,不执行硬盘上的程序,因此也被称为系统进 ...

  2. UNIX环境高级编程——进程管理和通信(总结)

    进程管理与通信 进程的管理 进程和程序的区别: 进程: 程序的一次执行过程   动态过程,进程的状态属性会发生变化 程序:存放在磁盘上的指令.数据的有序集合  是个文件,可直观看到 程序program ...

  3. UNIX环境高级编程——进程基本概述

    一.什么是进程 从用户的角度来看进程是程序的一次执行过程.从操作系统的核心来看,进程是操作系统分配的内存.CPU时间片等资源的基本单位.进程是资源分配的最小单位.每一个进程都有自己独立的地址空间与执行 ...

  4. UNIX环境高级编程——进程控制

    一.进程标识符 ID为0的进程是调度进程,常常被称为交换进程.该进程是内核的一部分,它并不执行任何磁盘上的程序,因此也被称为系统进程.进程ID 1通常是init进程,在自举过程结束时由内核调用.ini ...

  5. UNIX环境高级编程——进程关系

    一.终端的概念 在UNIX系统中,用户通过终端登录系统后得到一个Shell进程,这个终端成为Shell进程的控制终端(Controlling Terminal),控制终端是保存在PCB中的信息,而我们 ...

  6. UNIX环境高级编程——进程环境

    一.main函数 C程序总是从main函数开始.当内核执行C程序时,在调用main前先调用一个特殊的启动例程.可执行程序文件将此启动例程指定为程序的起始地址--这是由连接编译器设置的,而连接编译器则由 ...

  7. Unix环境高级编程—进程关系

    终端登录 网络登录 进程组 getpgrp(void) setpgid(pid_t pid, pid_) 会话: 是一个或多个进程组的集合,通常由shell的管道将几个进程编成一组. setsid(v ...

  8. Unix环境高级编程—进程控制(二)

    一.函数wait和waitpid 今天我们继续通过昨天那个死爹死儿子的故事来讲(便于记忆),现在看看wait和waitpid函数. #include<sys/wait.h> pid_t w ...

  9. 高级UNIX环境编程7 进程

    每个程序都会收到一张环境表 extern char **environ; c程序的存储空间布局: 正文段:共享,只读 初始化数据段:存函数以外的赋值 非初始化数据段(bbs):block starte ...

随机推荐

  1. 大数加法 HDU 1002

    #include <iostream> #include <cstring> #include <string> #include <cstdio> # ...

  2. python 基础(十) 面向对象

    面向对象 一.概念 类(class): 用来描述具有相同属性和方法的对象的集合 对象是类的实例化 类变量:类变量在整个实例化的对象中是共用的.定义在类中 并且是函数体外的 实例变量:只能作用于 当前类 ...

  3. ZROI提高组模拟赛05总结

    ZROI提高组模拟赛05总结 感觉是目前为止最简单的模拟赛了吧 但是依旧不尽人意... T1 有一半的人在30min前就A掉了 而我花了1h11min 就是一个简单的背包,我硬是转化了模型想了好久,生 ...

  4. Unity Shader入门精要学习笔记 - 第6章 开始 Unity 中的基础光照

    转自冯乐乐的<Unity Shader入门精要> 通常来讲,我们要模拟真实的光照环境来生成一张图像,需要考虑3种物理现象. 首先,光线从光源中被发射出来. 然后,光线和场景中的一些物体相交 ...

  5. Oracle如何创建表空间

    create user frame identified by tiger; grant create session to frame; grant create table to frame; g ...

  6. 关于IE兼容的问题

    以下内容,均来自不同的网站,非本人原创,只是收集一下放在一起! =============================== [一行代码解决各种IE兼容问题,IE6,IE7,IE8,IE9,IE10 ...

  7. DVWA之跨站请求伪造(CSRF)

    CSRF全称是Cross site request forgery ,翻译过来就是跨站请求伪造. CSRF是指利用受害者尚未失效的身份认证信息(cookie,会话信息),诱骗其点击恶意链接或者访问包含 ...

  8. SVN中的check out与export的区别

    http://blog.csdn.net/zndxlxm/article/details/7763116 check out跟check in对应,export跟import对应. check out ...

  9. HDU 6041 I Curse Myself(点双联通加集合合并求前K大) 2017多校第一场

    题意: 给出一个仙人掌图,然后求他的前K小生成树. 思路: 先给出官方题解 由于图是一个仙人掌,所以显然对于图上的每一个环都需要从环上取出一条边删掉.所以问题就变为有 M 个集合,每个集合里面都有一堆 ...

  10. WPF中实现两个窗口之间传值

    在使用WPF的时候,我们经常会用到窗体之间传值,下面示例主窗口传值到子窗口,子窗口传值到主窗口的方法. 一.主窗口向子窗口传值 主窗口向子窗口传值主要方法就是在子窗口建立一个接收主窗口值的变量,然后实 ...