• 管道和信号的简单用法


    2015.3.3
    星期二 阴天

    IPC:进程间通信
    pipe:无名管道:只能用于具有亲缘关系的进程之间
    fifo: 有名管道:可以使互不相关的两个进程互相通信,有名管道可以通过路径名来指出,并且在文件系统中可见,通过文件io操作,不支持lseek()

    管道创建:

    无名:调用pipe();
    有名管道:1.mkfifo(),2.open

    信号的处理:有一个阶段:“革命的前夜”


    实现进程间通信,用系统调用pipe()建立一个管道,两个子进程分别向管道中各写一句话,父进程从管道中读出来,并显示。
    下面的代码有很多细节处理不好,仅供参考,基本功能能实现。

    alarm();
    pause();需要给信号设置一个处理函数,否则程序会被直接杀掉

    信号处理的方法:
    signal();部署一个信号处理函数
    信号集函数;

    #include <unistd.h>
    #include <stdio.h>
    #include <stdlib.h>

    int pid1,pid2;

    int main(int argc,char **argv)
    {
    int fd[2];
    char outpipe[100], inpipe[100];

    pipe(fd);
    while((pid1 = fork()) == -1);

    if(pid1 == 0)
    {
    sprintf(outpipe,"child 1 process is sending message!");
    write(fd[1],outpipe,50);
    sleep(2);
    exit(0);
    }

    else
    {
    while((pid2 = fork()) == -1);

    if(pid2 == 0)
    {
    sprintf(outpipe,"child 2 process is sending message!");
    write(fd[1],outpipe,50);
    sleep(2);
    exit(0);
    }
    else
    {
    wait(NULL); //同步
    read(fd[0],inpipe,50);
    printf("%s ",inpipe);
    sleep(1);
    wait(NULL);
    read(fd[0],inpipe,50);
    printf("%s ",inpipe);
    wait(NULL);
    exit(0);
    }
    }
    }


    程序运行效果:

    lg@lg-desktop:/mnt/hgfs/source test/file IO$ gcc pipe51.c
    lg@lg-desktop:/mnt/hgfs/source test/file IO$ ./a.out
    child 2 process is sending message!
    child 1 process is sending message!
    lg@lg-desktop:/mnt/hgfs/source test/file IO$

    有名管道的创建,读,写操作:

    创建:
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <string.h>
    #include <errno.h>

    #define BUFFER_SIZE 1024

    int main(int argc,char **argv)
    {
    int fd;

    if(argc < 2)
    {
    fprintf(stdout,"Usage:%s<filename> ",argv[0]);
    exit(-1);
    }

    if(mkfifo(argv[1],0644) < 0)
    {
    fprintf(stderr,"mkfifo() filed : %s ",strerror(errno));
    exit(-1);
    }

    return 0;
    }

    写操作:

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

    #define BUFFER_SIZE 1024

    int main(int argc,char **argv)
    {
    int fd;

    if(argc < 2)
    {
    fprintf(stdout,"Usage:%s<filename> ",argv[0]);
    exit(-1);
    }

    if((fd = open(argv[1],O_WRONLY)) < 0)
    {
    fprintf(stderr,"open fifo %s for writting faile:%s ",argv[1],strerror(errno));
    exit(-1);
    }

    fprintf(stdout,"open fifo %s for writting successed. ",argv[0]);
    char buffer[BUFFER_SIZE];
    ssize_t n;

    while(fgets(buffer,BUFFER_SIZE,stdin))
    {
    if((n = write(fd,buffer,strlen(buffer))) < 0)
    {
    fprintf(stderr,"write() failed on fifo : %s ",strerror(errno));
    break;
    }
    }

    return 0;
    }


    读操作:

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

    #define BUFFER_SIZE 1024

    int main(int argc,char **argv)
    {
    int fd;

    if(argc < 2)
    {
    fprintf(stdout,"Usage:%s<filename> ",argv[0]);
    exit(-1);
    }

    if((fd = open(argv[1],O_RDONLY)) < 0)
    {
    fprintf(stderr,"open fifo %s for reading faile:%s ",argv[1],strerror(errno));
    exit(-1);
    }

    fprintf(stdout,"open fifo %s for reading successed. ",argv[0]);
    char buffer[BUFFER_SIZE];
    ssize_t n;

    while(1)
    {
    if((n = read(fd,buffer,BUFFER_SIZE)) < 0)
    {
    fprintf(stderr,"read failed on %s:%s ",argv[1],strerror(errno));
    exit(-1);
    }
    else if(n == 0)
    {
    fprintf(stderr,"peer closed fifo. ");
    break;
    }
    else
    {
    buffer[n]='';
    fprintf(stdout,"read %d bytes from :%s",n,buffer);
    }
    }

    return 0;
    }

    注:三个程序分别实现相应的功能,执行时,创建三个可执行文件,分别先执行创建的程序,再执行读写程序,这里:读写端同时打开才读写操作才能实现,否则会阻塞

    信号函数的使用:

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

    pid_t pid;

    void driver_handler(int signo);
    void saler_handler(int signo);

    int main(int argc, char **argv)
    {
    if((pid = fork()) < 0)
    {
    perror("fork");
    exit(-1);
    }
    if(pid > 0)
    {
    signal(SIGTSTP,driver_handler);
    signal(SIGINT,SIG_IGN);
    signal(SIGQUIT,SIG_IGN);
    signal(SIGUSR1,driver_handler);
    signal(SIGUSR2,driver_handler);
    while(1)
    {
    pause();
    }
    }
    else
    {
    signal(SIGINT,saler_handler);
    signal(SIGQUIT,saler_handler);
    signal(SIGTSTP,SIG_IGN);
    signal(SIGUSR1,saler_handler);
    signal(SIGUSR2,SIG_IGN);
    while(1)
    {
    pause();
    }
    }

    return 0;
    }

    void driver_handler(int signo)
    {
    if(signo == SIGUSR1)
    {
    printf("Let's gogogo! ");
    }

    if(signo == SIGUSR2)
    {
    printf("Stop the bus! ");
    }

    if(signo == SIGTSTP)
    {
    kill(pid,SIGUSR1);
    }
    }

    void saler_handler(int signo)
    {
    pid_t ppid = getppid();
    if(signo == SIGINT)
    {
    kill(ppid,SIGUSR1);
    }

    if(signo == SIGQUIT)
    {
    kill(ppid,SIGUSR2);
    }

    if(signo == SIGUSR1)
    {
    printf("please get off the bus ");
    kill(ppid,SIGKILL);
    exit(0);
    }
    }

    ***************************************************************************************************************************************************************
    ***************************************************************************************************************************************************************
    ***************************************************************************************************************************************************************
    ***************************************************************************************************************************************************************

  • 相关阅读:
    ubuntu18【合上盖子不休眠】
    linux和windows双系统开机显示 Minimal BASHlike line editingis supported xxxxxx
    Linux下opera不支持h5播放器的解决方法
    linux openjdk路径
    Linux安装redis tar.gz
    dpkg 安装deb文件
    Linux破解Navicat15
    kali设置grub主题
    kali安装git tar.gz
    kali 安装 teamviewer 显示检测到wayland
  • 原文地址:https://www.cnblogs.com/cnlg/p/4312162.html
Copyright © 2020-2023  润新知