IO进程线程、3,信号通信、4,共享内存、5,消息队列

一、信号通信

信号通信:

        异步通信: 当我们关注某一个事件时,如果事件未发生,我们继续完成自己任务, 当事件发生后,它会给我们传递一个信号,此时我们再回头完成对应事件 信号处理方式: 捕捉:信号发生后,我们通过某些方法(函数)获取对应信号然后自定义该信号的处理方式

忽略:信号不在执行对应的默认操作(SIGKILL/SIGSTOP除外)

默认:

        kill指令: kill -n pid: 给pid进程发送 第n个信号 kill -n -pid: 给pid进程组发送第n个信号 kill -n -1: 给除了init进程和本进程外其它所有进程发送第n个信号

int kill(int pid, int sig);
返回值: 成功 0 失败 -1
int pid: 0 同组进程; -1 除init外的所有进程 ; >0 进程号==pid
int sig: 对应的信号
            
unsinged int alarm(unsinged int s);
unsinged int s: 定时秒数
unsinged int: 失败 -1; 如果之前调用alarm函数,则返回上一个闹钟剩余时间

二、IPC对象

1.每个IPC对象有唯一的ID(操作对应IPC对象的凭证) 2.IPC对象创建后一直存在,直到被显示地删除(函数/命令) 3.每一个IPC对象有一个关联的key(多个进程找到同一个IPC对象,事先约定好) ipcs/ipcrm(查看操作指令) key == 0 表示私有 key: IPC_PRIVATE(0):表示私有 ftok():生产key值

key_t ftok(const char *path, int proj_id);
返回值: 成功 返回key 失败返回 EOF
const char *path: 存在切可访问的文件路径
int proj_id: 用于生成key的数字,不能为0 且低八位有效

1、共享内存

效率最高的进程间通信方式,进程可以直接读写内存,而不需要任何数据拷贝

共享内存在内核空间创建,只有被映射到用户空间才可以使用

当多个进程同时访问共享内存时,需要加入同步或者互斥机制配合使用 操作步骤: 1.创建/打开共享内存

int shmget(key_t key, int size, int shmflg);
    返回值: 成功时返回共享内存ID, 失败返回EOF
    key_t key: 和共享内存关联的key, IPC_PRIVATE/ftok生成
    int size: 共享内存的大小,以字节为单位
    int shmflg: 共享内存标志位是否新建(IPC_CREAT|0666)及操作权限

2.映射到用户空间

void *shmat(int shmid, const void *shmaddr, int shmflg);
返回值: 成功 映射后的地址, 失败 返回(void *)-1
int shmid: 对应的共享内存ID
const void *shmaddr: 要映射后的地址, NULL表示由系统自动映射
int shmflg: 0表示可读可写;SHM_RDONLY表示只读

3.读/写共享内存(通过指针访问/指针类型根据共享内存中存放的数据类型决定)

fgets()
strcpy()
...

4.撤销共享内存映射

int shmdt(void *shmaddr);
返回值: 成功返回0, 失败返回EOF
void *shmaddr: 共享内存映射的地址
注意: 一般不使用共享内存时应及时撤销映射,进程结束时自动撤销所有的共享
    内存映射,若未取消映射,则无法删除对应的共享内存

5.删除共享内存(只是标记,直到所有相关进程退出时才删除)

int shmctl(int shmid, int cmd, struct shmid_ds *buf);
返回值:成功 0,失败 EOF
int shmid: 要删除的共享内存ID
int cmd: 要执行的操作 IPC_STAT IPC_SET IPC_RMID
struct shmid_ds *buf: 存放共享内存的属性(删除时为NULL)

==注意==: 每块共享内存有大小限制: ipcs -l (cat /proc/sys/kernel/shmmax ) 多进程使用时,应由第一个进程创建,所有映射取消时才会真正的删除

2、消息队列:

1.使用最普遍 ​ 2.消息队列ID来唯一标识 ​ 3.是一个消息的列表,用户可以添加/读取消息 ​ 4.消息队列可以按照类型来发送/接收 ​ 使用步骤: ​ 1.打开/创建消息队列 msgget

int masgget(key_t key, int msgflg);
            返回值: 成功对应消息队列ID, 失败返回EOF
            key_t key: 关联的KEY 
            int msgflg: 标志位 IPC_CREAT|0666

2.向消息队列发送消息 msgsnd

int msgsnd(int msgid, const void *msgp, size_t size, int msgflg);
        返回值: 成功返回0, 失败返回 -1
        int msgid: 对应消息队列ID
        const void *msgp: 要发送消息的缓冲区地址
        size_t size: 指定本次发送消息的长度(正文长度)
        int msgflg: 标志位 0/IPC_NOWAIT (0阻塞 IPC_NOWAIT非阻塞(消息队列满时))
        注:

消息格式:

1.根据需求定义结构体类型
2.首成员类型必须为long,代表消息的类型
3.其它成员都属于正文
typedef struct{
    long mtype; //类型,正整数
    ...         //成员
}MSG;

3.从消息队列接收消息 msgrcv

int msgrcv(int msgid, void *msgp, size_t size, long msgtype, int msgflg);
        返回值: 成功返回消息的长度, 失败 -1
        int msgid: 消息队列的id
        void *msgp: 接收的消息存放的缓冲区
        size_t: 指定接收消息的长度(小于实际长度,剩余消息丢失;超过无影响)
        long msgtype: 指定接收消息的类型(0 按时间接收最早的消息; 负数按照优先级接收(几乎没见到))
        int msgflg: 标志位 0/IPC_NOWAIT

4.控制消息队列 msgctl

int msgctl(int msgid, int cmd, struct msqid_ds *buf);
        返回值: 成功0, 失败 -1
        int msgid: 消息队列ID
        int cmd: 要执行的操作 IPC_STAT/IPC_SET/IPC_RMID
        struct msqid_ds *buf: 存放消息队列属性的地址

你可能感兴趣的:(算法,开发语言,进程间通信)