Linux 进程间通信

Linux 进程间通信的方式可以分为三大类:

  • 管道
  • 信号
  • IPC,又可分为三类
    • 共享内存
    • 消息队列
    • 信号量

管道

管道是 Linux 内核中的数据结构,类似于队列,管道中的特性如下:

  • 数据只能读取一次,读取后消失,不可再次读
  • 半双工通信,两端都可以用来写数据,但一端开始写数据的话,另一端只能用来读
  • 无数据时,读会阻塞;数据写满时,会写阻塞

用过命令行的人,对管道应该不陌生。例如,查看 bash 进程状态:

ps aux | grep bash

上面命令创建了一个匿名管道,将前面命令的输出作为后面命令的输入。

匿名管道

通过 pipe 命令可以创建匿名管道。只能用于有血缘关系的进程之间通信。

#include <unistd.h>

int pipe(int pipefd[2]);

因为需要返回读端和写端两个文件描述符,所以通过数组参数来实现。其中 pipefd[0] 是读端,pipefd[1] 是写端。成功返回 0,失败返回 -1。

示例 注意,必须在 fork 子进程之前创建匿名管道

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

int main() {
        char readBuf[10];
        int fd[2];
        int pid;
        int ret = pipe(fd);
        pid = fork();
        if (pid < 0) {
                printf("fork error\n");
                return -1;
        }
        if (pid == 0) {
                read(fd[0], readBuf, 10);
                printf("readBuf is:%s\n", readBuf);
                close(fd[0]);
        } else {
                int status;
                sleep(3);
                write(fd[1], "hello linux\n", 10);
                close(fd[1]);
                waitpid(pid, &status, 0);
        }
		return 0;
}

有名管道

如果想用管道实现无血缘关系的进程间通信,必须使用有名管道。创建有名管道时,会在磁盘上创建管道文件,文件类型是 p

Linux 中一切皆文件,常见的文件类型有:
- 常规文件
d 目录文件
p 管道文件
l 连接文件
s 套接字文件
b block device 块设备文件,如硬盘。可以以块为单位进行随机访问
c character device 字符设备文件,如键盘。可以以字符为单位进行线性访问

#include <sys/types.h>
#include <sys/stat.h>

int mkfifo(const char *pathname, mode_t mode);

mkfifo 会在文件系统中创建管道文件,任何进程打开这个文件后通过读写操作就可以实现进程间通信。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

int main() {
        int ret = mkfifo("myfifo", 0777);
        if (ret == -1) {
                perror("mkfifo");
                exit(EXIT_FAILURE);
        }
        sleep(4);
        int fd = open("./myfifo", O_RDWR);
        write(fd, "hello linux\n", 10);
        close(fd);
        return 0;
}

信号

发送信号

Linux 中有 3 个函数用来发送信号:

  • kill:可以向指定进程发送指定信号
  • raise:向进程自身发送信号
  • alarm:向进程自身发送 SIGALRM 信号

Linux 中,如果想杀死某个进程,只需要执行命令 kill -9 pid。其中,-9 表示发送 9 号信号(SIGKILL 结束进程),pid 表示要操作的进程的 ID。Linux 中向进程发送信号的系统调用跟这个命令类似:

#include <sys/types.h>
#include <signal.h>

int kill(pid_t pid, int sig);

接收信号

Linux 中有 3 中方式接收信号:

  • while 循环
  • sleep 一段时间
  • pause 休眠,等待被信号唤醒

处理信号

如果不想用系统默认的信号处理方式,可以用 signal 函数绑定自己的函数来处理信号。

IPC

共享内存

消息队列

信号量

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值