首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

C fork/exec,带有非阻塞管道IO

首先,我们需要了解C语言中的fork()和exec()函数。fork()函数用于创建一个新的进程,而exec()函数用于在当前进程中执行一个新的程序。在C语言中,我们可以使用fork()和exec()函数来实现进程间通信。

下面是一个简单的示例代码,展示了如何使用fork()和exec()函数来实现进程间通信:

代码语言:c
复制
#include<stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>

int main() {
    int pipefd[2];
    pid_t pid;
    char buffer[1024];

    // 创建管道
    if (pipe(pipefd) == -1) {
        perror("pipe");
        exit(EXIT_FAILURE);
    }

    // 创建子进程
    pid = fork();
    if (pid == -1) {
        perror("fork");
        exit(EXIT_FAILURE);
    }

    if (pid == 0) {
        // 子进程
        close(pipefd[1]); // 关闭写端
        read(pipefd[0], buffer, sizeof(buffer)); // 从管道中读取数据
        printf("Child process received: %s\n", buffer);
        close(pipefd[0]); // 关闭读端
        exit(EXIT_SUCCESS);
    } else {
        // 父进程
        close(pipefd[0]); // 关闭读端
        write(pipefd[1], "Hello, child process!", sizeof("Hello, child process!")); // 向管道中写入数据
        close(pipefd[1]); // 关闭写端
        wait(NULL); // 等待子进程结束
        printf("Parent process sent message to child process.\n");
        exit(EXIT_SUCCESS);
    }
}

在这个示例代码中,我们首先创建了一个管道,然后使用fork()函数创建了一个子进程。子进程负责从管道中读取数据,而父进程负责向管道中写入数据。最后,父进程等待子进程结束,并输出一条消息。

需要注意的是,这个示例代码中的管道是阻塞的,即当子进程正在读取数据时,父进程会被阻塞,直到子进程读取完毕。如果需要实现非阻塞的管道IO,可以使用select()函数来监控管道的状态,以实现非阻塞的读写操作。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

本文帮你在Unix玩转C语言

不带缓冲的io不是iso c的组成部分,是posix的组成部分。 对内核而言,所有的打开的文件都通过文件描述符(负整数)引用。0 1 2 分别是输入 输出 错误 的描述符。...低速系统调用是可能会使进程永远阻塞的一类系统调用。 阻塞IO:操作无法完成,立即出错返回【不停在那,以便进行下一步处理,类似trylock试加锁】。...两种方法指定描述符为阻塞IO:open时O_NONBLOCK;fcntl(fd, cmd, &lock)打开 O_NONBLOCK标志。...IO多路转接【两个描述符】:执行阻塞read,阻塞是对整个进程阻塞,如果多个通路【一般是无限循环读、写】想要相互不影响,就得fork多个进程,每个进程处理各自的文件描述符。...用阻塞read轮询描述符消耗cpu。 IO多路转接思想:构造一张描述符表,调用一个函数,直到表中描述符中的一个已经准备好IO时,该函数返回,告诉进程哪些描述符可以IO。主要用于终端IO和网络IO

82410

【操作系统】进程间的通信——管道

因为调用exec并不创建新进程,所以前后的进程ID并未改变。exec只是用另一个新程序替换了当前进程的正文、数据、堆和栈段。...小示例1:主进程关闭写进程后,无法给子进程使用管道发送数据,此时子进程使用read函数进行数据的读取,如果 没有数据可读,则会进行阻塞,代码&结果如下所示: 解释:主进程循环5次,给子进程发送数据。...如果有多个进程,将每个进程的写端都关闭了,read()也将不会阻塞。 小提示: 为了避免不必要的麻烦,例如没有可读数据时read函数的阻塞,我们可以将没用的管道端口关闭。...5: 把管道作为标准输入和标准输出 把管道作为标准输入和标准输出的优点: 子进程使用exec启动新进程时,就不需要再把管道的文件描述符传递给新程序了。...相关参考——linux系统编程之进程(五):exec系列函数(execl,execlp,execle,execv,execvp)使用 main5.c #include #include

53620

基础知识_操作系统

五种IO模型 11. 如何理解阻塞阻塞,同步与异步? 12. 页表为什么要分级 13. 页面置换算法 14. 死锁产生的四个条件 15. 处理死锁的四个方法 16. 信号量以及PV原语 17....进程间通讯有哪些 1.管道 面向字节流,创建匿名管道的时候使用int pipe(int fd[2]),产生两个文件描述符,从fd[0]读出数据,从fd[1]写入数据,然后fork进程,就可以实现两个进程间的通讯...五种IO模型 阻塞IO阻塞IOIO复用、信号驱动IO、异步IO 如何理解阻塞阻塞,同步与异步? 举例 老张爱喝茶,废话不说,煮开水。...所谓阻塞阻塞,仅仅对于老张而言。立等的老张,阻塞;看电视的老张,阻塞。 情况1和情况3中老张就是阻塞的,媳妇喊他都不知道。 虽然3中响水壶是异步的,可对于立等的老张没有太大的意义。...所以一般异步是配合阻塞使用的,这样才能发挥异步的效用。

42720

C语言 进程

系统中每个进程有唯一的id,在C语言中用pid_t类型表示。进程的状态,有运行、挂起、停止、僵尸等状态。进程切换时需要保存和恢复的一些CPU寄存器。描述虚拟地址空间的信息。描述控制终端的信息。...exec函数用fork创建子进程后执行的是和父进程相同的程序(但有可能执行不同的代码分支),子进程往往要调用一种exec函数以执行另一个程序。...当进程调用一种exec函数时,该进程的用户空间代码和数据完全被新程序替换,从新程序的启动例程开始执行。调用exec并不创建新进程,所以调用exec前后该进程的id并未改变。...,这时有进程从管道读端读数据,那么管道中剩余的数据都被读取后,再次read会阻塞,直到管道中有数据可读了才读取数据并返回.如果所有指向管道读端的文件描述符都关闭了(管道读端的引用计数等于0),这时有进程向管道的写端...如果有指向管道读端的文件描述符没关闭(管道读端的引用计数大于0),而持有管道读端的进程也没有从管道中读数据,这时有进程向管道写端写数据,那么在管道被写满时再次write会阻塞,直到管道中有空位置了才写入数据并返回

1.2K10

unix环境高级编程(下)-高级IO和进程间通信篇

该篇主要包括: 高级io 先介绍记录锁的概念和记录锁的数据结构。然后介绍阻塞io阻塞IO,异步ioIO多路转接等概念,后者都是针对前者更优的技术。...阻塞IO 1.1 概念 阻塞io使得与磁盘io有关的系统调用永远不会被阻塞 这些io相关的系统调用有:open,read,write 如果这种操作不能完成,则调用立即出错返回 1.2 如何指定非阻塞...2.3 锁的隐含继承和释放 进程终止时,所建立的锁全部释放 关闭文件描述符时,文件描述符引用的文件上的任何一把锁都被释放 fork产生的子进程不继承父类设置的锁 执行exec后,新进程可以继承原程序的锁...IO多路转接 4.1 阻塞io 读取一个文件描述符对数据,如果没有数据就一直阻塞住 缺点:长时间阻塞在同一个文件描述符,另一个文件描述符虽然有很多数据却得不到及时处理 4.2 阻塞io 将两个文件描述符都设置为阻塞的...popen先执行fork,然后调用exec以执行cmdstring,并返回标准io文件指针。如果type=“r“,文件指针连接到cmdstring的标准输出。

1.3K42

Linux的进程线程及调度

1.2.2 进程创建与消亡相关API 1) system() 通过调用shell启动一个新进程 2) exec() 以替换当前进程映像的方式启动一个新进程 3) fork() 以复制当前进程映像的方式启动一个新进程...比如按CTRL-C组合键会发送SIGINT信号,进程里可以捕捉到这个信号进行相应处理。 2) 管道PIPE 一切皆文件,管道的操作也是类似文件的操作。...管道是在亲属进程(同一父进程创建出的进程)之间进行数据传输的。 3) 命名管道FIFO 命名管道可用于在无亲属关系之前是进程间通信。...无MMU的CPU使用vfork创建进程,父进程将一直阻塞直到子进程exit或exec。 vfork和fork的本质区别是,vfork中的父子进程共用同一片内存区。...运行到目前为止vruntime最小的进程 同时考虑了CPU/IO和nice 总是找vruntime最小的线程调度。

4.1K41

linux下进程相关操作

exec和exit之前,子进程与父进程共享数据段 2) fork不对父子进程的执行次序进行任何限制;而在vfork调用中,子进程先运行,父进程挂起,直到子进程调用了exec或exit之后,父子进程的执行次序才不再有限制...(3)exec函数族 在fork后的子进程中使用exec函数族,可以装入和运行其它程序(子进程替换原有进程,和父进程做不同的事)。...fork创建一个新的进程就产生了一个新的PID,exec启动一个新程序,替换原有的进程,因此这个新的被 exec 执行的进程的PID不会改变(和调用exec的进程的PID一样)。...B.只能用于父子进程或者兄弟进程之间(具有亲缘关系的进程); C.单独构成一种独立的文件系统:管道对于管道两端的进程而言,就是一个文件,但它不是普通的文件,它不属于某种文件系统,而是自立门户,单独构成一种文件系统...当打开一个FIFO时,阻塞标(O_NONBLOCK)产生下列影响: A、在一般情况中(没有说明O_NONBLOCK),只读打开要阻塞到某个其他进程为写打开此FIFO。

2.1K50

Swoole的多进程模块

,读键盘输入可以重定向为管道读取数据 3.swoole_process提供了exec接口,创建的进程可以执行其他程序,与原PHP父进程之间可以方便的通信 创建进程 函数原型: Swoole\Process...启用此选项后,在子进程内输出内容将不是打印屏幕,而是写入到主进程管道。读取键盘输入将变为从管道中读取数据。默认为阻塞读取。...同步 vs 异步: 默认为同步阻塞模式, 可以使用 swoole_event_add() 添加管道到 swoole 的 event loop 中, 实现异步IO ?...msgKey, 可以通过此访问不同的消息队列 有数据大小限制, 默认 8192 阻塞 vs 阻塞: 阻塞模式下 pop()空消息队列/push()满消息队列会阻塞, 阻塞模式可以直接返回 swoole...hello 主进程');#推送到主进程 }); $process->useQueue(1, 2 | swoole_process::IPC_NOWAIT);//启用消息队列,争抢模式,阻塞

76630

Swoole的多进程模块

,读键盘输入可以重定向为管道读取数据 3.swoole_process提供了exec接口,创建的进程可以执行其他程序,与原PHP父进程之间可以方便的通信 创建进程 函数原型: Swoole\Process...启用此选项后,在子进程内输出内容将不是打印屏幕,而是写入到主进程管道。读取键盘输入将变为从管道中读取数据。默认为阻塞读取。...同步 vs 异步: 默认为同步阻塞模式, 可以使用 swoole_event_add() 添加管道到 swoole 的 event loop 中, 实现异步IO 管道通信是swoole_process...有一个 msgKey, 可以通过此访问不同的消息队列 有数据大小限制, 默认 8192 阻塞 vs 阻塞: 阻塞模式下 pop()空消息队列/push()满消息队列会阻塞, 阻塞模式可以直接返回...hello 主进程');#推送到主进程 }); $process->useQueue(1, 2 | swoole_process::IPC_NOWAIT);//启用消息队列,争抢模式,阻塞

1K20

【翻译】XV6-DRAFT as of September 3,2014 第0章 操作系统接口

读操作会一直阻塞直到不可能有新数据到来,这就是为什么我们在执行wc之前要关闭子进程的写端口。如果wc指向一个管道的写端口,那么wc就永远看不到eof了。...xv6 shell使用了与上面代码类似的方法,实现了如grep fork sh.c | wc -l这样的管道(在8450行)。...管道的右端可能也是一个带有管道的命令(例如 a|b|c),它fork两个新的子进程(一个b,一个c)。...第三,管道允许同步:两个进程可以使用一对管道来进行彼此间的通信,调用进程的read操作会被阻塞,直到另一个进程调用write完成数据的发送。...路径a/b/c指向了一个名为c的文件或目录,c在文件目录b下,而目录b又处于目录a下,a又是处于root目录之下。

58460

深入理解Node.js 进程与线程(8000长文彻底搞懂)

单线程的一些说明 Node.js 虽然是单线程模型,但是其基于事件驱动、异步阻塞模式,可以应用于高并发场景,避免了线程创建、线程之间上下文切换所产生的资源开销。...Node.js 中的进程与线程 Node.js 是 Javascript 在服务端的运行环境,构建在 chrome 的 V8 引擎之上,基于事件驱动、阻塞I/O模型,充分利用操作系统提供的异步 I/O...fork开启子进程 Demo fork开启子进程解决文章起初的计算耗时造成线程阻塞。...Libuv本身是由C++语言实现的,Node中的苏塞IO以及事件循环的底层机制都是由libuv实现的。 libuv架构图 ?...在Window环境下,libuv直接使用Windows的IOCP来实现异步IO。在Windows环境下,libuv使用多线程来模拟异步IO

1.1K30

深入理解Node.js 进程与线程(8000长文彻底搞懂)

单线程的一些说明 Node.js 虽然是单线程模型,但是其基于事件驱动、异步阻塞模式,可以应用于高并发场景,避免了线程创建、线程之间上下文切换所产生的资源开销。...Node.js 中的进程与线程 Node.js 是 Javascript 在服务端的运行环境,构建在 chrome 的 V8 引擎之上,基于事件驱动、阻塞I/O模型,充分利用操作系统提供的异步 I/O...fork开启子进程 Demo fork开启子进程解决文章起初的计算耗时造成线程阻塞。...Libuv本身是由C++语言实现的,Node中的苏塞IO以及事件循环的底层机制都是由libuv实现的。 libuv架构图 ?...在Window环境下,libuv直接使用Windows的IOCP来实现异步IO。在Windows环境下,libuv使用多线程来模拟异步IO

2.3K10

node中子进程同步输出

管道 通过“child_process”模块fork出来的子进程都是返回一个ChildProcess对象实例,ChildProcess类比较特殊无法手动创建该对象实例,只能使用fork或者spawn,而且与...具体实现 var child = require('child_process') , fs = require('fs'); var childProcess = child.exec(cmd...使用系统兼容较好的exec函数完成基本功能,在shell命令执行完毕后写入状态信息到某些临时文件,最后通过循环不断读取新写入该临时文件的数据。...由于在shell命令执行过程中需要模拟同步效果,因此在循环中不仅仅获取新写入的数据,同时需要模拟I/O阻塞操作,此处shelljs的作者通过尝试所有的同步IO API,发现fs.writeFileSync...操作可以较少的减轻CPU利用率,因此使用该函数阻塞I/O。

1.2K60

深入理解Node.js 进程与线程(8000长文彻底搞懂)

单线程的一些说明 Node.js 虽然是单线程模型,但是其基于事件驱动、异步阻塞模式,可以应用于高并发场景,避免了线程创建、线程之间上下文切换所产生的资源开销。...Node.js 中的进程与线程 Node.js 是 Javascript 在服务端的运行环境,构建在 chrome 的 V8 引擎之上,基于事件驱动、阻塞I/O模型,充分利用操作系统提供的异步 I/O...fork开启子进程 Demo fork开启子进程解决文章起初的计算耗时造成线程阻塞。...Libuv本身是由C++语言实现的,Node中的苏塞IO以及事件循环的底层机制都是由libuv实现的。 libuv架构图 ?...在Window环境下,libuv直接使用Windows的IOCP来实现异步IO。在Windows环境下,libuv使用多线程来模拟异步IO

91920

【Linux】进程控制

2、fork 函数返回值 学过 C/C++ 的时候同学都知道,一个函数最多只能有一个返回值,那么我们应该如何理解 fork 函数有两个返回值呢?...(4)、阻塞阻塞等待 waitpid 函数的第三个参数用于指定父进程的等待方式: 其中,options 为0代表阻塞式等待,options 为 WNOHANG 代表阻塞式等待; 阻塞式等待即当父进程执行到...轮询 轮询是指父进程在阻塞式状态的前提下,以循环方式不断的对子进程进行进程等待,直到子进程退出。...,阻塞式等待用0来标识,阻塞式等待用宏 WNOHANG 来标识; 由于阻塞式等待不会等待子进程退出,所以我们需要以轮询的方式来不断获取子进程的退出信息。...execl && execlp exec 函数的使用其实很简单,第一个参数为我们要替换的程序的路径,,如果该程序在PATH环境变量中,且 exec 函数带有 “p”,我们可以不带路径,只写函数名; 我们以

4K00
领券