【linux系统理论】——进程间通信

一、进程间如何通信
中心思想:需要一个额外的空间,一个进程往里写,另一个进程往外读。

  • 空间可以是磁盘或内存。
  • 空间里读写时,属于生产者-消费者模型,保证同步问题。(同步问题,操作系统内部已经实现,使用者直接使用即可)

1. 管道

简介
磁盘中存储的是文件,所以将磁盘作为空间时,这种方法叫做管道(pipe),
匿名管道

  • 创建匿名管道文件,文件描述符fd[0]和fd[1]
  • fd[0]用于读文件内容,fd[1]用于向文件写内容
  • 只能用于父子进程间通信
  • 只能单向传输
    在这里插入图片描述
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <ctype.h>
#include <sys/wait.h>

int main()
{
    char *message = "hello world";
    char buf[100];
	int pipe_fd[2];
	if (pipe(pipe_fd) < 0) { //创建管道
         perror("pipe ");
         exit(EXIT_FAILURE);
    }

    if (fork() == 0) //child
    {
         printf("wait read\n");
         read(pipe_fd[0], buf, sizeof(buf)); // 管道空阻塞
         printf("buf = %s\n", buf);
         close(pipe_fd[0]);
    } else {
        sleep(1);
        write(pipe_fd[1], message, strlen(message)+1);
        printf("write over\n");
        close(pipe_fd[1]);
        wait(NULL); //父进程等待子进程结束,防止子进程变成孤儿
   }

   return 0;
}
# 结果
wait read
write over
buf = hello world

命名管道
用于非亲缘关系间的通信。

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


int main()
{
        int ret;
        ret = mkfifo("/tmp/fif", 0777);
        if (ret < 0) {
                perror("mkfifo");
                exit(EXIT_FAILURE);
        }

        int fd = open("/tmp/fif", O_RDWR);
        if (fd < 0) {
                perror("open error");
                exit(EXIT_FAILURE);
        }
        char buf[100];
                read(fd, buf, 100);
        printf("buf = %s\n", buf);

        close(fd);
        return 0;
}
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <ctype.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>



int main()
{
        char buf[100];
         int fd = open("/tmp/fif", O_RDWR);
        if (fd < 0) {
                perror("open error");
                exit(EXIT_FAILURE);
        }

                write(fd, "hello", sizeof("hello"));
        close(fd);

        return 0;
}

2. 共享内存(POSIX标准下)

使用步骤

  • 在内存中申请空间,shm-open,得到文件描述符
  • 设置文件大小,ftruncate
  • 映射文件到内存,mmap
  • 从内存中拷贝内容
  • 关闭文件
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <ctype.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>


int main()
{
        const char *sham_name = "my_shm";
        char data[] = "Hi, Shard memory";
        int shm_fd = shm_open(sham_name, O_CREAT|O_RDWR, 0777);
        if (shm_fd < 0) {
                printf("shm_fd error\n");
        }
        ftruncate(shm_fd, 4096);

        void *ptr = mmap(0, 4096, PROT_READ|PROT_WRITE, MAP_SHARED, shm_fd, 0);
        printf("ptr = %p\n", ptr);
        memcpy(ptr, data, sizeof(data)+1);
        printf("ptr = %s\n", (char *)ptr);
        close(shm_fd);

        return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <ctype.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>


int main()
{
        int shm_fd;
        const char *sham_name = "my_shm";
        shm_fd = shm_open(sham_name, O_RDONLY, 0777);
        if (shm_fd < 0) {
                perror("shm_open error");
                exit(EXIT_FAILURE);
        }
        void * m_ptr = mmap(0, 4096, PROT_READ, MAP_SHARED, shm_fd, 0);
        if (m_ptr ==  MAP_FAILED) {
                perror("m_ptr error");
                exit(EXIT_FAILURE);
        }
        printf("shared mem contents %s\n", (char *)m_ptr);
        close(shm_fd);

        shm_unlink(sham_name);
        return 0;
}

运行结果
shared mem contents Hi, Shard memory

共享内存实现机制

3. 消息队列

在这里插入图片描述
使用方法:

mqd_t mq = mq_open("/my_queue", O_CREATE|O_RDWR, 0644, &attr);
mq_send(mq, buffer, msg_len, 0);// 最后一个参数是优先级
mq_receive(mq, buffer, MAX_SIZE, NULL);// 最后一个参数是优先级
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值