进程间通信的方式

进程间通信的方式

匿名管道

  • 半双工,具有固定的读端和写端,只能读取一次
  • 只能用于有亲属关系的进程间通信
  • 可以看成是一种特殊的文件,对于它的读写也可以使用普通的read、write函数。但是它不 是普通的文件,并不属于其他任何文件系统,只能用于内存中。
  • Int pipe(int fd[2]);当一个管道建立时,会创建两个文件文件描述符,要关闭管道只需将这两 个文件描述符关闭即可
nt main(){
    int fd[2];
    int ret;
    ret = pipe(fd);
    if(ret==-1)perror("make pipe error:");
    pid_t pid = fork();
    if(pid==-1)perror("make pid error:");
    else if(pid>0){
        close(fd[0]);
        dup2(fd[1], STDOUT_FILENO);
        execlp("ls","ls",NULL);
    }else if(pid==0){
        close(fd[1]);
        dup2(fd[0],STDIN_FILENO);
        execlp("Wc", "Wc", "-1",NULL);
}

命名管道

  • 半双工,具有固定的读端与写端,只能读取一次
  • 可以在无关的进程间进行通信
  • FIFO有路径名与之相关联,它以一种特殊设备文件形式存在于文件系统中;FIFO在磁盘上没有数据块,文件仅仅是用来标识内核中的一条通道。
int mkfifo(const char* pathname, mode_t mode);

消息队列

  • 消息队列,是消息的连接表,存放在内核中。一个消息队列由一个标识符来标识;
  • 消息队列是面向记录的,其中的消息具有特定的格式以及特定的优先级;
  • 消息队列独立于发送与接收进程。进程终止时,消息队列及其内容并不会被删除;
  • 消息队列可以实现消息的随机查询

信号量

  • 信号量是一个计数器,信号量用于实现进程间的互斥与同步,而不是用于存储进程间通信 数据;
  • 信号量用于进程间同步,若要在进程间传递数据需要结合共享内存;
  • 信号量基于操作系统的PV操作,程序对信号量的操作都是原子操作;

共享内存

  • 共享内存,指两个或多个进程共享一个给定的存储区
  • 共享内存是最快的一种进程通信方式,因为进程是直接对内存进行存取
  • 因为多个进程可以同时操作,所以需要进行同步

原理

现代操作系统,对于内存管理,采用的是虚拟内存技术,也就是每个进程都有自己独立的虚拟内存空间,不同进程的虚拟内存映射到不同的物理内存中。所以,即使进程 A 和 进程 B 的虚拟地址是一样的,其实访问的是不同的物理内存地址,对于数据的增删查改互不影响。

共享内存的机制,就是各拿出一块虚拟地址空间来,映射到相同的物理内存中。这样这个进程写入的东西,另外一个进程马上就能看到了,都不需要拷贝来拷贝去,传来传去,大大提高了进程间通信的速度。

两种实现方式

int shmget(key_t key, size_t size, int shmflg);//创建共享内存
void *shmat(int shmid, const void *shmaddr, int shmflg);//挂接共享内存
int shmdt(const void *shmaddr);//取消关联共享内存
int shmctl(int shmid, int cmd, struct shmid_ds *buf);//销毁共享内存

套接字

此方法主要用于在客户端和服务器进程之间通过网络进行通信。也有本地套接字来完成本地进程间的通信

信号

  • 信号其实就是一个软件中断。它由内核负责产生发送和处理。信号由终端或者进程调用系统函数产生。
  • 信号有抵达和未决两种状态,未决的主要原因是信号阻塞。
  • 信号处理方式主要有:

Linux内核的进程控制块PCB是一个结构体, task struct,除了包含进程id,状态,工作目录,用户id,组id, 文件描述符表,还包含了信号相关的信息,主要指阻塞信号集和未决信号集。

阻塞信号集(信号屏蔽字): 将某些信号加入集合,对他们设置屏蔽,当屏蔽x信号后,再收到该信号,该信号 的处理将推后(解除屏蔽后)

未决信号集: 信号产生,未决信号集中描述该信号的位立刻翻转为1,表信号处于未决状态。当信号被处理对应位翻 转回为0。这一时刻往往非常短暂。

两个不可被丢弃和捕捉的信号

  1. SIGKILL:无条件终止进程
  2. SIGSTOP:暂停进程执行

信号捕捉的两个函数

sighandler_t signal(int signum, sighandler_t handler);
//参数解释:

    //signum:更改的信号值
    //handler:函数指针,要更改的动作是什么
    //实际上,该函数内部也调用了sigaction函数。
int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
//参数解释:

    //signum:待更改的信号值
    //void     (*sa_handler)(int);//函数指针,保存了内核对信号的处理方式
    //void     (*sa_sigaction)(int, siginfo_t *, void *);//
    //sigset_t   sa_mask;//保存的是当进程在处理信号的时候,收到的信号
    //int        sa_flags;//SA_SIGINFO,OS在处理信号的时候,调用的就是sa_sigaction函数指针当中保存的值0,在处理信号的时候,调用sa_handler保存的函数
    //void     (*sa_restorer)(void);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值