一起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,‘\0‘,sizeof(output));

    if(mkfifo(p_name,0777) == 0) // create pipe
    {
        pid = fork();
        if(pid > 0)
        {
            printf("father running \n");
            fd = open(p_name,O_RDONLY); //open by read mode
            if(fd == -1)
            {
                printf("open pipe file failed \n");
                return 1;
            }
        }
        else if(pid == 0)
        {
            printf("son running \n");
            fd = open(p_name,O_WRONLY); //open by write mode
            if(fd == -1)
            {
                printf("open pipe file failed \n");
                return 1;
            }

            count = write(fd,input,strlen(input));    // write the dato into pipe
            printf("son process write %d characters,they are : %s \n",count,input);
            close(fd);
        }
        else
        {
            printf("create process failed \n");
            return 1;
        }
    }
    else
    {
        printf("create fifo failed \n");
        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 \n",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”,父进程接着从管道中读取了该数据,进而实现的了父子进程之间的数据传输,也就是进程之间的通信

各位看官,关于使用信号进行进程间通信的例子咱们就说到这里。欲知后面还有什么例子,且听下回分解 。


时间: 2024-10-06 02:46:34

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

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

各位看官们,大家好.上一回中咱们说的是进程间通信的样例.这一回咱们说的样例是:使用管道进行进程间通信. 闲话休提,言归正转. 让我们一起talk C栗子吧! 我们在前面的的章回中介绍了使用管道进行进程问的通信,时间不长,相信大家还记得.今天.我们介绍第二种进程间通信的方式:管道.大家都知道,我们使用信号在进程间通信时,本质上发送的是一个数值,假设想在进程之间发送一些数据时信号就无能为力了.此时,管道就派上了用场. 我们能够通过管道在进程之间发送数据. 接下来我们就具体介绍一下管道. 管道相似我们

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

各位看官们,大家好,上一回中咱们说的是使用管道进行进程间通信概述的例子,这一回咱们说的例子是:使用第一种管道进行进程间通信.闲话休提,言归正转.让我们一起talk C栗子吧! 我们在上一回中介绍了三种管道,这一回中我们介绍第一种管道(伪管道)及其使用方法.主要是让大家明白如何使用管道进行进程间的通信. 第一种管道我称之为伪管道.在介绍它之前,我们先介绍两个函数:popen和pclose. popen函数的原型 FILE * popen(const char * command, const ch

一起talk C栗子吧(第八十五回:C语言实例--使用信号进行进程间通信二)

各位看官们,大家好,上一回中咱们说的是使用信号进行进程间通信的样例,这一回咱们接着上一回的内容,继续说该样例.闲话休提.言归正转. 让我们一起talk C栗子吧. 我们在上一回中举了使用信号进行进程间通信的样例,在该样例中.我们通过终端发出信号.当进程收到该信号后让它运行系统对信号定义的默认动作.这一回.我们再来举一个使用信号进行进程间通信的样例,只是.我们发送和处理信号的方式和上一回的样例不一样.在接下来的样例中,我们在一个进程中使用kill产生信号.在另外一个进程中接收而且依照自己的方式处理

一起talk C栗子吧(第一百三十一回:C语言实例--C程序内存布局三)

各位看官们,大家好.上一回中咱们说的是C程序内存布局的样例,这一回咱们继续说该样例.闲话休提,言归正转.让我们一起talk C栗子吧. 看官们,关于C程序内存布局的样例,我们在前面的两个章回都介绍过了,这一回我们将对前面章回中的内容进行总结和提示. 内存布局总结 C程序的内存布局主要有四个分区:代码区,数据区(data和bss).堆区和栈区.能够使用readelf -S filename查看各个分区的内存地址.这四个分区在内存中从低地址空间開始依次向高地址延伸.我们再次使用前面章回中的图直观地展

一起talk C栗子吧(第八十四回:C语言实例--使用信号进行进程间通信一)

各位看官们,大家好,上一回中咱们说的是进程间通信的例子,这一回咱们说的例子是:使用信号进行进程间通信.闲话休提,言归正转.让我们一起talk C栗子吧! 我们在上一回中提到过进程之间通信需要解决的三个问题,时间不长,我想大家都记得.今天我们就来解决第一个问题:进程之间如何进行通信. 信号的概念 在解决问题前,我们先介绍一下信号.信号是Unix/Linux系统提供的一种机制,它本质上一种软件中断.信号为我们提供了一种异步的事件处理方法,当进程收到信号时就会采取某种操作.例如,当进程收到终止信号(S

一起talk C栗子吧(第十八回:C语言实例--输出十六进制)

各位看官们,大家好,从今天开始,我们讲大型章回体科技小说 :C栗子,也就是C语言实例.闲话休提, 言归正转.让我们一起talk C栗子吧! 看官们,上一回中咱们说的是栈的例子,这一回咱们说的例子是:输出十六进制. 看官们,我想熟悉C语言的朋友们,对于输出十六进制的内容,肯定都会使用printf函数进行格式化输出. 不过,有时候想输出十六进制时就会有点"不识庐山真面目,只缘身在此山中"的感觉.我在前面的例子中 有一个关于进制转换的例子.当时输出十六进制时使用分别判断10到15,然后依据判

一起talk C栗子吧(第六回:C语言实例--生成随机数)

各位看官们,大家好,从今天开始,我们讲大型章回体科技小说 :C栗子,也就是C语言实例.闲话休提, 言归正转.让我们一起talk C栗子吧! 看官们,上一回中咱们说的是数组巧妙赋值的例子,这一回咱们说的例子是:生成随机数. 看官们学过C语言的话,还记得如何生成随机数吧.忘记了?那么我们一起说说.使用rand()函数可以生 成随机数,不过,它生成的随机数是一种伪随机数.因为重复执行程序的话,得到的随机数是一样.生成 随机数的函数是通过一个固定的数值来计算随机数的,我们可以通过srand()函数来指定

一起talk C栗子吧(第九回:C语言实例--最大公约数)

各位看官们,大家好.从今天開始,我们讲大型章回体科技小说 :C栗子,也就是C语言实例.闲话休提, 言归正转.让我们一起talk C栗子吧! 看官们.上一回中咱们说的是素数的样例.这一回咱们说的样例是:最大公约数. 看官们,最大公约数也叫最大公因数.两个整数中的公约数有好几个.这些公约数中最大的一个就叫作最 大公约数.当然了,这是数学中的一个概念,假设不明确了,能够查阅相关的数学知识. 最大公约数的求法有好几种.最经常使用的是辗转相除法,也叫欧几里德算法.该算法的原理例如以下: 1.假设正整数a除

一起talk C栗子吧(第十七回:C语言实例--栈二)

各位看官们,大家好,从今天开始,我们讲大型章回体科技小说 :C栗子,也就是C语言实例.闲话休提, 言归正转.让我们一起talk C栗子吧! 看官们,上一回中咱们说的是栈和特点和基本操作,最后通过顺序存储的方式实现了栈,这一回咱们继续 说栈,不过咱们这一回说的是栈的链式存储方式. 在代码中通过双向链表来实现栈的链式存储.入栈操作沿着表头到表尾的方向进行,出栈操作与其正好相 反(就把它当作双向链表的一个使用实例吧).栈的结点可以看作是链表中的结点,对栈的操作,可以看 作是在链表中进行插入或者删除结点