• step4 . day7 进程间的通信方式


     进程间的通信方式:

    无名管道(pipe)

    有名管道 (fifo)

    信号(signal)

    system v5的进程间通信方式

    共享内存(share memory)

    消息队列(message queue)

    信号灯集(semaphore set)

    套接字(socket)

    1.无名管道

    只能用于具有亲缘关系的进程之间的通信

    单工的通信模式,具有固定的读端和写端

    无名管道创建时会返回两个文件描述符,分别用于读写管道

    创建无名管道
    #include <unistd.h>
    int pipe(int pfd[2]);

    返回值:成功时返回0,失败时返回EOF
    参数:pfd 包含两个元素的整形数组,用来保存文件描述符
    pfd[0]用于读管道;pfd[1]用于写管道


    #include<stdio.h>
    #include <unistd.h>
    #include <string.h>
    #define N 32

    int main(int argc, const char *argv[])
    {

    pid_t pid;
    int pfd[2];
    char buf[N];
    if(pipe(pfd)<0){
    perror("pipe");
    return -1;
    }
    pid = fork();
    if(pid < 0){
    perror("fork");
    return -1;
    }else if(pid == 0){
    while(1){
    strcpy(buf, "hello world from child process");
    write(pfd[1],buf,strlen(buf));
    sleep(1);
    }
    }
    else{
    while(1){
    memset(buf,0,strlen(buf));
    read(pfd[0],buf,N);
    printf("recevie :%s ",buf);
    }
    }
    return 0;
    }

    2.有名管道

    有名管道具有如下特点:
    对应管道文件,可用于任意进程之间进行通信
    打开管道时可指定读写方式
    通过文件IO操作,内容存放在内存中

    管道的创建
    #include <unistd.h>
    #include <fcntl.h>
    int mkfifo(const char *path, mode_t mode);

    返回值:成功时返回0,失败时返回EOF
    参数: path 创建的管道文件路径
    mode 管道文件的权限,如0666

    使用: open()
    read()
    write()

    进程1


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

    #define N 32
    int main(int argc, const char *argv[])
    {
    int re;
    unlink("myfifo");
    re= mkfifo("myfifo",0666);

    if(re<0){
    perror("makfifo");
    return -1;
    }
    char buf1[N];
    char buf2[N];
    strcpy(buf1,"hello world");
    int fifofd;
    fifofd = open("myfifo",O_RDWR);
    while(1){
    write(fifofd,buf1,N);
    sleep(1);

    memset(buf2,0,N);
    re = read(fifofd,buf2,N);
    if(re>0){
    printf("%s ",buf2);
    }
    }

    return 0;
    }

    进程2


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

    #define N 32
    int main(int argc, const char *argv[])
    {
    int re;

    char buf1[N];
    char buf2[N];
    strcpy(buf2,"how are you");
    int fifofd;
    fifofd = open("myfifo",O_RDWR);
    while(1){
    memset(buf1,0,N);
    re = read(fifofd,buf1,N);
    if(re>0){
    printf("%s ",buf1);
    }

    write(fifofd,buf1,N);
    sleep(1);
    }

    return 0;
    }

    3.信号通信

    信号是在软件层次上对中断机制的一种模拟,是一种异步通信方式
    linux内核通过信号通知用户进程,不同的信号类型代表不同的事件
    Linux对早期的unix信号机制进行了扩展

    进程对信号有不同的响应方式 
    缺省方式
    忽略信号
    捕捉信号

    终端命令 kill -l 可以查看信号

    signal 函数定义

    typedef void (*sighandler_t)(int);

    sighandler_t signal(int signum, sighandler_t handler);

    或者void (*signal(int signo, void (*handler)(int)))(int);

    定义分解

    void (* xxxx )(int);

    xxxx = signal(int signo, aaa)

    aaa = void (*handler)(int)

    返回值:成功时返回原先的信号处理函数,失败时返回SIG_ERR
    参数 :signo 要设置的信号类型
    handler 指定的信号处理函数: SIG_DFL代表缺省方式; SIG_IGN 代表忽略信号;

    signal函数不发信号,不阻塞,它使用回掉函数改变信号的行为。

    #include <stdio.h>
    #include <signal.h>

    void handle(int sig){
    if(sig == SIGINT){
    printf("I got a ctrl+C signal ");
    }else if(sig == SIGQUIT){
    printf("I got a quit signal ");
    }else{
    printf("other siganl ");
    }

    }

    int main(){

    signal(SIGINT,handle);
    signal(SIGQUIT,handle);
    signal(SIGHUP,handle);
    while(1){
    sleep(1);
    }

    }

  • 相关阅读:
    .ssh/config 文件的解释算法及配置原则
    不fq安装 golang tools
    iOS 组件化的几篇文章
    第一把机械键盘 ikbc C-87
    我推荐的 Java Web 学习路线
    【吐槽向】iOS 中的仿射变换
    Spring 对缓存的抽象
    Spring 事务管理笔记
    Swift 笔记汇总
    Java 类加载器
  • 原文地址:https://www.cnblogs.com/huiji12321/p/11343161.html
Copyright © 2020-2023  润新知