• 一起talk C栗子吧(第九十回:C语言实例--使用管道进行进程间通信三)



    各位看官们,大家好,上一回中咱们说的是使用管道进行进程间通信的样例。这一回咱们说的样例是:使用管道进行进程间通信。只是使用管道的方式不同样。闲话休提,言归正转。让我们一起talk C栗子吧!

    我们在前面章回中介绍了三种管道。这一回我们介绍第三种管道及其使用方法

    最主要还是让大家明确怎样使用管道进行进程间的通信。

    第三种管道我称之为真正意义上的管道。该管道还有另外一个名字:命名管道(FIFO)。在介绍它之前。我们先介绍一个函数:mkfifo.

    mkfifo函数的原型

    int mkfifo(const char *filename, mode_t mode)
    • 该函数用来创建一个管道文件;
    • 该函数的第一个參数是字符串,用来表示管道文件的名字;
    • 该函数的第二个參数是文件訪问权限,用来表示管道文件的权限,比如:0764;
    • 该函数会返回一个文件描写叙述符,能够通过该文件描写叙述符来操作管道;
    • 该函数执行成功时返回0,否则返回-1。

    明确这个函数的使用方法后,我们接下来介绍命名管道的使用方法.

    mkfifo函数的使用方法

    • 1.使用mkfifo函数创建一个命名管道。
    • 2.在进程A中使用open打开管道(打开方式为写),这时会得到一个fd;
    • 3.使用write通过fd在管道中写入数据;
    • 4.使用close关闭步骤2中得到的fd;
    • 5.在进程B中使用open打开管道(打开方式为读),这时会得到一个fd;
    • 6.使用read通过fd从管道中读取数据;
    • 7.使用close关闭步骤5中得到的fd。

    我们能够看到,进程A在mkfifo创建的管道中写入数据,进程B从该管道中读取数据。进程A和B通过该管道实现了进程之间的通信。通信的内容为数据。

    我们接下来使用具体的样例进行说明,以下是具体的代码

    int main()
    {
        char input[] = "IPC by pipe";
        char output[BUFSIZ+1];
        char p_name[] = "/tmp/test_fifo";
        int count = 0;
        int fd;
        int stat_value;
        pid_t pid,pid_res;
    
        memset(output,'',sizeof(output));
    
        if(mkfifo(p_name,0777) == 0) // create pipe
        {
            pid = fork();
            if(pid > 0)
            {
                printf("father running 
    ");
                fd = open(p_name,O_RDONLY); //open by read mode
                if(fd == -1)
                {
                    printf("open pipe file failed 
    ");
                    return 1;
                }
            }
            else if(pid == 0)
            {
                printf("son running 
    ");
                fd = open(p_name,O_WRONLY); //open by write mode
                if(fd == -1)
                {
                    printf("open pipe file failed 
    ");
                    return 1;
                }
    
                count = write(fd,input,strlen(input));    // write the dato into pipe
                printf("son process write %d characters,they are : %s 
    ",count,input);
                close(fd);
            }
            else
            {
                printf("create process failed 
    ");
                return 1;
            }
        }
        else
        {
            printf("create fifo failed 
    ");
            return 1;
        }
    
            pid_res = wait(&stat_value);
    
            if(pid_res > 0)
            {
                count = read(fd,output,BUFSIZ);       // read the data from pipe
                printf("father process read %d characters,they are: %s 
    ",count,output);
    
                close(fd);
            }
    
        return 0;
    }

    通过上面的代码。大家能够发现,我们首先创建了一个命名管道。然后用fork创建了子进程。而且在子进程中向管道中写入数据。接着在父进程中读取数据,只是父进程使用wait函数等待子进程写入数据后才去管道中读取数据。这便是进程之间相互排斥的应用。假设不这样做的话,父进程从管道中读取数据时,子进程还没有把数据写入管道。

    看官们,正文中就不写代码了。具体的代码放到了我的资源中,大家能够点击这里下载使用。

    以下是程序的执行结果,请大家參考:

    ./s                                                       //执行编译后的程序
    father running                                            //父进程在执行
    son running                                               //子进程在执行
    son process write 11 characters,they are : IPC by pipe    //子进程向管道中写入数据
    father process read 11 characters,they are: IPC by pipe   //父进程从管道中读取数据

    我们通过上面的程序执行结果能够看到,子进程在管道中写入了数据“IPC by pipe”,父进程接着从管道中读取了该数据,进而实现的了父子进程之间的传输数据,也就是进程之间的通信

    各位看官,关于使用信号进行进程间通信的样例咱们就讲到这里。

    欲知后面还有什么样例,且听下回分解 。


  • 相关阅读:
    virtual方法和abstract方法的使用(轉載)
    C# 如何寫入cookie
    Literal的一般用法,与Label对比 MSDN上的解释
    With temp as---sql语句用法 转
    GridView __DataKey 使用
    .net里radiobutton 两个怎么才能让他只选择一个
    Server.Transfer()与Response.Redirect()区别
    OnInit 事件
    ajax中Sys.WebForms.PageRequestManager的事件激发顺序
    Linux CentOS 查看某个进程打开的文件(文件描述符)
  • 原文地址:https://www.cnblogs.com/jzssuanfa/p/7221749.html
Copyright © 2020-2023  润新知