zoukankan      html  css  js  c++  java
  • LINUX C系统编程学习笔记进程通信(一)

    进程间通信(一)

     1.为什么需要进程间通信?

    ① 数据转移

    一个进程需要它的数据发送给另一个进程

    ② 资源共享

    多进程之间共享同样的资源

    ③ 通知事件

    一个进程需要想另一个或一组进程发送消息,通知他们发生了什么事件

    ④ 进程控制

    一个进程控制另一个进程的执行

    一.管道通信 

    管道定义:

    管道是单向的,先进先出的,它把一个进程的输出和另一个进程的输出连接在一起,一个进程(写进程)在管道尾部写入数据,另一个进程(读进程)从管道头部读出数据。

    管道分类:

    无名管道: 用与父进程和子进程之间的通信

    有名管道: 用于运行于同一系统中任意两进程间的通信

    无名管道:    

     int pipe(int filedis[2]):

    创建无名管道,管道建立时,它会创建两个文件描述符,

    filedis[0] 用于读管道;filedis[1] 用于写管道

    关闭管道只需要将这两个文件描述符关闭即可,用close逐个关闭 

     例: 

    #include <stdio.h>
    #include <errno.h>     //---------关于errno.h看这http://www.cnblogs.com/riky/archive/2008/02/02/1062750.html
    #include <unistd.h>
    #include <stdlib.h>

    int main(void)
    {
        int pipe_fd[2]
        if (pipe(pipe_fd) < 0)
        {
            printf("pipe creat error!\n");
            return -1;
        }
        else
            printf("pipe creat success!\n");
        close (pipe_fd[0]);
        close (pipe_fd[1]);

    注意:必须要在系统调用fork之前调用pipe(),否则子进程将不会继承文件描述符

     例:

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

    int main(void)
    {
        int pipe_fd[2];
        pid_t pid;
        char buf_r[100];
        char *p_wbuf;
        int r_num;
        memset(buf_r,0,sizeof(buf_r));
    //创建管道
        if (pipe(pipe_fd) < 0)
        {
            printf("pipe creat error\n");
            return -1;
        }
    //创建子进程
        if ((pid = fork()) == 0)    //判断是否为子进程
        {
            printf("\n");
            close(pipe_fd[1]);
            sleep(2);
            if ((r_num = read(pipe_fd[0],buf_r,100)) > 0)
            {
                printf("%d numbers read form the pipe is %s\n",r_num,buf_r);
            }
            close(pipe_fd[0]);
            exit(0);
        }
        else if (pid > 0)
        {
            close(pipe_fd[0]);
            if ( write(pipe_fd[1],"Hello",5) != -1)
                printf("parent write Hello!\n");
            if (write(pipe_fd[1],"Pipe",5) != -1)
                printf("parent write Pipe!\n");
            close(pipe_fd[1]);
            sleep(3);
        waitpid(pid,NULL,0);
        exit(0);
        }

    下面是写


    命名管道:

    #include <sys/types.h>

    #include <sys/stat.h>

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

    pathname: FIFO文件名 

    mode:属性(同文件操作)

    创建了FIFO,就可以用OPEN打开它,一般的文件访问函数(close,read,write等)都可用于FIFO 。

     当打开FIFO时,非阻塞标志(O_NONBLOCK)将对以后读写产生的影响:

      1· 没有使用O_NONBLOCK:访问要求无法满足时,进程阻塞,如试图读取空的FIFO,将导致进程阻塞。

    2·使用O_NONBLOCK: 访问要求无法满足时,不发生阻塞,立刻返回,errno是ENXIO。

    例:

    这个是读 :

     /*

      *********             *********
      ********* fifo_read.c *********
      *********             *********
    */

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

    #define FIFO "/home/scrat/code/myfifo"

    int main(int argc,char **argv)
    {
        char buf_r[100];
        int fd;
        int nread;
        
    //  创建管道
        
        if ((mkfifo(FIFO,O_CREAT|O_EXCL) < 0) && (errno != EEXIST))
            printf("prepraing for reading bytes ~~~~~");
    //  打开管道
        
        fd = open(FIFO,O_RDONLY|O_NONBLOCK,0);
        if (fd == -1)
        {
            perror("open");
            exit(1);
        }
        while(1)
        {
            memset(buf_r,0,sizeof(buf_r));
            if ((nread = read(fd,buf_r,100)) == -1)
            {
                if (errno == EAGAIN)
                    printf("no data yet\n");
            }
        printf("read %s form FIFO\n",buf_r);
        sleep(1);
        }
        pause();       //   暂停,等待
        unlink(FIFO);  //   删除文件FIFO
    }

    下面这个是写: 

    /*
      *********              *********
      ********* fifo_write.c *********
      *********              *********
    */
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <errno.h>
    #include <fcntl.h>

    #define FIFO_SERVER "/home/scrat/code/myfifo"

    int main(int argc, char ** argv)
    {
        int fd;
        char w_buf[100];
        int nwrite;

    //  打开管道

        fd = open(FIFO_SERVER,O_WRONLY|O_NONBLOCK,0);
        if (argc == 1)
        {
            printf("Please send something\n");
            exit(-1);
        }
        strcpy(w_buf,argv[1]);

    // 向管道写入数据

        if ((nwrite = write(fd,w_buf,100)) == -1)
        {
            if (errno == EAGAIN)
                printf("The FIFO has not been read yet.please try later\n");
        }
        else
            printf("write %s to the FIFO\n",w_buf);


        return 0;


    ----------------------------------------------在穷无非讨饭,不死终会出头。
  • 相关阅读:
    Java里的时间类以及函数
    递归方法理解快速排序算法
    Java操作读取写入文本TXT及XML文件内容
    java控制Office套件API(POI加JXL)网上摘录留工作备查
    通过直接预分区的方式建表
    自用JavaMail实现
    阿里巴巴java开发手册学习记录,php版
    PHP 常用的header头部定义汇总
    这里有123个黑客必备的Python工具!
    PHP/JS中获取当前页面的完整URL
  • 原文地址:https://www.cnblogs.com/scrat/p/2559755.html
Copyright © 2011-2022 走看看