C 从管道块读取直到子进程终止

2023-12-13

父进程创建 N 个子进程,每个子进程都用 exec 替换自己。父进程和 exec 之间通过一系列管道进行通信(int pipelinefd[N][2];)

The exec使用以下命令写入管道:

char msg[50];
sprintf( msg, "\tsent from pid: %d, pi= %f", getpid(), pi);
printf("%s\n",msg);
write(i1, msg, strlen(msg)+1);

家长读到这些:

for (i=0;i<N;i++) {
   close(pipefd[i][1]);  // close the write end of the pipe in the parent

   read(pipefd[i][0], buffer, sizeof(buffer));
   printf("\n-C-\n");

   if (buffer[0] == '\t'){
     printf("%s\n",buffer);
   }
   int j;
   for (j=0; j<100; j++) {
      buffer[j]='\n';
   }
   close(pipefd[i][0]);
}

现在的问题是only子进程终止后,读取将被解除阻塞并打印缓冲区。 我想要做的是在 exec 写入管道后立即打印缓冲区。

以下是全部代码:

父文件:

#include <signal.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/time.h>
#include <string.h>

#define N 5
pid_t *pid;
int pipefd[N][2];

int flag = 0;
int count_ctrl_c = 0;
void signal_handler(int sig){
    signal(sig, SIG_IGN);
    printf("\n");

    flag = 1;
    signal(SIGINT, signal_handler);
}

int main(int argc, char *argv[]) {


    int i;
    for (i = 0; i < N; i++) {
        pipe(pipefd[i]);
    }

    int parent_pid = getpid();
    pid= (pid_t *)malloc(N * sizeof(pid_t));

    for (i = 0; i < N; i++) {
        pid[i] = fork();
        if (pid[i] == 0) //The parent process will keep looping
        {

            char b[50];
            sprintf( b, "%d", i+1);

            char i0[50];
            sprintf( i0, "%d", pipefd[i][0]);

            char i1[50];
            sprintf( i1, "%d", pipefd[i][1]);

            char par_id[50];
            sprintf( par_id, "%d", parent_pid);

            execl("***the/path/to/exec/calculate***", b,i0,i1,par_id,NULL);
        }
    }

    if (parent_pid == getpid()) {
        signal(SIGINT, signal_handler);


        while(1){
            if (flag){

                printf("\n-A-\n");
                char buffer[100];
                int i;
                for (i=0;i<N;i++) {
                    // Apostellei to shma SIGUSR2 se ola ta paidia tou
                    kill(pid[i], SIGUSR2);
                }

                printf("\n-B-\n");
                for (i=0;i<N;i++) {
                    close(pipefd[i][1]);  // close the write end of the pipe in the parent

                    read(pipefd[i][0], buffer, sizeof(buffer));
                    printf("\n-C-\n");
                    if (buffer[0] == '\t'){
                        printf("%s\n",buffer);
                    }
                    int j;
                    for (j=0; j<100; j++) {
                        buffer[j]='\n';
                    }
                    close(pipefd[i][0]);
                }
                //exit(0);
                printf("finished reading\n");

                flag = 0;
                count_ctrl_c++;
                if (count_ctrl_c == 2) {
                    exit(0);
                }
            }

        }
    }
}

计算.c

#include <signal.h>
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/time.h>
#include <string.h>

#define N 5

int i0,i1,parent_pid;

int flag = 0;
int time_to_term = 0;
double pi;

void signal_handler2(int sig);
void signal_handler(int sig);

void signal_handler2(int sig){
    signal(sig, SIG_IGN);
    signal(SIGALRM, SIG_IGN);
    flag = 1;
    signal(SIGUSR2, signal_handler2);
    signal(SIGALRM, signal_handler);
}

void signal_handler(int sig){
    signal(sig, SIG_IGN);
    pid_t pid = getpid();
    printf("time: %d, pid: %d, pi: %1.10f\n", time_to_term, pid, pi);
    exit(0);
}

int main(int argc, char *argv[]) {
    int pid;
    signal(SIGINT, SIG_IGN);
    signal(SIGUSR2, signal_handler2);
    signal(SIGALRM, signal_handler);

    time_to_term = atoi(argv[0]);   
    alarm(time_to_term);

    i0 = atoi(argv[1]);
    i1 = atoi(argv[2]);
    parent_pid = atoi(argv[3]);

    double mul = 1.0;
    double par = 2.0;
    pi = 3.0;

    while(1){


        pi = pi + (mul * (4.0 / (par * (par + 1.0) * (par + 2.0))));
        mul = mul * (-1.0);
        par += 2;

        sleep(1);

         if (flag) {
            signal(SIGALRM, SIG_IGN);
            close(i0);

            char msg[50];
            sprintf( msg, "\tsent from pid: %d, pi= %f", getpid(), pi);
             printf("%s\n",msg);
            write(i1, msg, strlen(msg)+1);

            close(i1);
            flag = 0;

            signal(SIGALRM, signal_handler);
            //exit(0);


        }
    }

}

解决此问题的一般提示:使用以下命令运行管道的两侧strace工具(您可以使用strace -f跟随分叉),以便您可以验证从管道中实际写入/读取的内容。

我怀疑在这种情况下,孩子什么也没写!这是因为您使用的 stdio 层(printf())检查它是否正在写入终端或其他任何东西。在终端的情况下,它会在每个换行符后刷新输出,但在其他情况下,它仅在写入较大的数据块(GNU 系统上为 8KiB)后刷新。尝试使用手动刷新输出fflush() after printf()。如果有帮助,您可以调整stdout缓冲模式使用设置vbuf().

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C 从管道块读取直到子进程终止 的相关文章

  • Qt 图表和数据可视化小部件

    我已经安装了 Qt 5 7 来尝试 Qt 图表和 Qt 数据可视化 但我在 Qt Designer 和 Qt Creator 中都找不到新的小部件 有什么建议我应该做什么才能让新的小部件出现在设计器中 我今天遇到了完全相同的问题 默认情况下
  • Linq - 从表达式 创建表达式

    我有一个谓词Expression
  • 如何在特定时间以毫秒精度触发 C# 函数?

    我有两台计算机 它们的时间通过 NTP 同步 确保时间仅相差几毫秒 其中一台计算机将通过 TCP 向另一台计算机发送一条消息 以在两台计算机上的未来指定时间启动某个 c 函数 我的问题是 如何在特定时间以毫秒精度 或更好 触发 C 中的函数
  • 生成多个随机数

    我想生成 25 个唯一的随机数并将它们列在控制台中 数字的长度应至少为 10 个字符 有什么简单的方法可以做到这一点吗 尝试将数字构建为字符串 并使用 HashSet 确保它们是唯一的 Random random new Random Ha
  • 将公历日期转换为儒略日期,然后再转换回来(随着时间)

    我正在编写一个程序 必须将当前的公历日期和时间转换为儒略日期 然后再转换回公历门 最终我需要添加能够添加年 月 日 小时 分钟和秒的功能 但我需要先解决这部分问题 现在我已经从公历日期转换为儒略日期 所以从逻辑上讲 我觉得我应该能够以某种方
  • 平滑手绘曲线

    我有一个允许用户绘制曲线的程序 但这些曲线看起来不太好 它们看起来摇摇欲坠 而且是手绘的 所以我想要一种能够自动平滑它们的算法 我知道平滑过程中存在固有的模糊性 因此它不会每次都完美 但这种算法似乎确实存在于多个绘图包中 并且它们工作得很好
  • 局部函数声明有什么用处吗?

    大多数像我这样的 C 程序员都曾犯过以下错误 class C int main C c declares a function c taking no arguments returning a C not as intended by m
  • 在没有 epsilon 的情况下可以将浮点数与 0.0 进行比较吗?

    我知道 要比较两个浮点值 需要使用一些 epsilon 精度 因为它们并不精确 但是 我想知道是否存在边缘情况 我不需要那个 epsilon 特别是 我想知道这样做是否总是安全的 double foo double x if x lt 0
  • 如何在C中同时运行两个子进程?

    所以我开始学习并发编程 但由于某种原因我什至无法掌握基础知识 我有一个名为 fork c 的文件 其中包含一个 main 方法 在此方法中 我将 main 分叉两次 分别进入子进程 1 和 2 在孩子 1 中 我打印了字符 A 50 次 在
  • ContentDialog 未与 UWP 中心对齐

    据我所知 ContentDialog的默认行为应该是使其在 PC 上居中并在移动设备上与顶部对齐 但就我而言 即使在 PC 上我也将其与顶部对齐 但我不明白发生了什么 我正在使用代码隐藏来创建它 这是我正在使用的代码片段 Creates t
  • 将 dataGridView 中选定的行作为对象检索

    我有一堂这样的课 public partial class AdressBokPerson public long Session get set public string F rnamn get set public string Ef
  • 对作为函数参数传递的指针使用删除

    删除作为函数参数传递的指针是否可以 并且合法 如下所示 include
  • 控制台应用程序中使用 Unicode 字符的 _tprintf

    我正在从 Unicode 构建的控制台应用程序 使用 C 和 Visual Studio 2008 执行这个简单的输出 此代码旨在在 Windows 上运行 tprintf L Some sample string n 一切正常 但是如果我
  • 如何将STL容器数据转储到gdb中?

    我无法在 gdb 中转储 STL 无序映射容器值 变量类型是 std unordered map var 我的 gdb 版本 7 7 1 GDB配置 configure host x86 64 linux gnu target x86 64
  • 配置:错误:无法运行C编译的程序

    我正在尝试使用 Debian Wheezy 操作系统在我的 Raspberry Pi 上安装不同的软件 当我运行尝试配置软件时 我尝试安装我得到此输出 checking for C compiler default output file
  • 更改 Xamarin.Forms 应用中顶部栏和底部栏(ControlsBar、StatusBar)的颜色

    无论如何 即使后面需要特定于平台的代码 也可以更改顶部栏 蓝色的 和底部栏 黑色的 的颜色吗 我希望添加对浅色和深色模式的支持 因此我希望能够在运行时更改它 有可能的 Android Using Window SetStatusBarCol
  • DataGridView 行背景颜色没有改变

    我想根据加载时的特定条件更改 DGV 行的背景颜色 即使在 Windows 窗体中也是如此 但我看不到任何 DGV 行的颜色有任何变化 谁能告诉我如何解决这个问题 private void frmSecondaryPumps Load ob
  • valgrind 在 Raspberry Pi 上返回未处理的指令

    我最近一直在尝试在运行 Debian GNU Linux7 0 喘息 的树莓派 型号 b 上使用 valgrind 来调试分段错误 每次我在编译的 C 程序上运行 valgrind 时 都会得到类似以下内容的信息 disInstr arm
  • 从对列表创建邻接列表类型结构

    在 C 中 我有 class Pair int val1 int val2 我有一个来自以下来源的配对列表 List
  • 如何在c#中创建多线程

    我需要监听机器中的所有串行端口 假设我的机器有 4 个串行端口 我必须创建 4 个线程并开始分别使用附加线程监听每个端口 我使用此代码来获取我的机器中的端口数量 private SerialPort comPort new SerialPo

随机推荐

  • Angularjs ng-show 方法被调用太多次[重复]

    这个问题在这里已经有答案了 我有一个 ng repeat 循环 它循环 3 个事件 在每个事件中 我想检查登录的用户是否是与该事件关联的团队的玩家 问题是 我的代码正在进入is player 每次加载页面大约30次 这显然会导致问题 因为它
  • 如何在 AngularJS 中正确使用指令

    我正在使用 AngularJS 上的指令执行第一步 但该指令对我不起作用 我有一个ng repeat list ul li li ul 正在被过滤 scope activeFilter filterValue 我正在尝试创建ng after
  • CreateProcess 成功,但 GetLastError() 返回访问被拒绝

    由于返回值冲突 我有点困惑CreateProcess and GetLastError 当我使用CreateProcess 以类似于下面的方式 它成功并似乎完成了所需的任务 然而 GetLastError 仍然返回访问被拒绝 如果访问被拒绝
  • RecursionError:使用 pickle.load() 调用 Python 对象时超出最大递归深度

    首先 我知道已经就这个特定错误提出了多个问题 但我找不到任何解决该错误发生在我身上的精确上下文的问题 我还尝试了为其他类似错误提供的解决方案 但没有任何区别 我正在使用 python 模块pickle将对象保存到文件并使用以下代码重新加载它
  • 使用警报框询问用户输入

    我希望用户在警报框中输入一段文本 HTML
  • 如何在 ASP.NET MVC 应用程序中设置一个控制器操作的请求超时

    我想增加应用程序中特定控制器操作的请求超时 我知道我可以在整个应用程序的 web config 中执行此操作 但我宁愿仅在这一个操作上更改它 Web config 示例
  • Pytest:使用其他固定装置作为输入的固定装置进行参数化单元测试

    我是参数化和装置的新手 仍在学习 我发现了一些使用间接参数化的帖子 但根据我的代码中的内容 我很难实现 如果有任何关于我如何实现这一目标的想法 我将不胜感激 我的 conftest py 中有几个固定装置 它们向测试文件中的函数 get f
  • 在geom_point中为ggplot2中的负值和正值设置不同的颜色

    给定一个数据框如下 df lt data frame city c bj sh gz sz price c 12 7 5 6 pct c 2 3 5 4 4 stringsAsFactors FALSE Out city price pct
  • 新的 Ember 应用程序出现黑屏

    我是 ember 新手 正在做一个入门教程构建一个简单的应用程序 当我创建一个新应用程序并启动服务器时 我尝试访问本地主机页面 http 本地主机 4200 在我的浏览器中但页面是空白的 浏览器窗口标题是我的应用程序名称 但没有应有的 欢迎
  • 如何删除匹配的标签但保留 JQuery 内容

    我有这样的 HTML div div class a content1 div content 2 div class a b content 3 b div div 我想删除 class a 的 div 但保留它们的内容 我最初的尝试是
  • 使用合并排序计算反转[关闭]

    Closed 这个问题是无法重现或由拼写错误引起 目前不接受答案 我用Python编写了一个合并排序程序 它运行得很好 但我修改了它来计算所涉及的反转次数 现在它给了我一个错误 这是我的代码 def merge list left righ
  • 调用未定义函数 session_start()

    我正在尝试使用 php 启动会话 但总是收到此错误 Fatal error Call to undefined function session start in www test test php on line 2 我的代码 复制表格h
  • Selenium moveByOffset 不执行任何操作

    我在 Linux Xubuntu 13 10 上使用 Firefox 28 0 运行最新的 selenium 2 41 我试图让 FirefoxDriver 将鼠标移到页面上 在我的测试中 我使用了有线网页 它有很多悬停激活的菜单 但是mo
  • Java中的逻辑运算符优先级

    我对此并不满意 http docs oracle com javase specs jls se7 html jls 15 html jls 15 22 它明确规定了以下内容 如果操作数表达式没有副作用 则每个运算符都是可交换的 and 这
  • VB.net Excel.worksheet().cells().Value

    尝试在 Excel 工作表中写入信息 但有一些奇怪的问题 我在谷歌上查看了信息 但没有结果 所以请帮忙 我添加引用Microsoft excel 14 0对象库 并导入 Microsoft Office interop 我需要从特定单元格获
  • 我可以使用哪些方法通过 Spotify 应用程序进行地理定位?

    Spotify Apps API 不允许 HTML5 地理定位 显然记录的 Location api 调用不起作用 正在从文档中删除 我可以使用哪些方法来对用户进行地理定位 查找网站访问者地理位置的解决方案及其建议http freegeoi
  • 变换后的宽度/高度

    应用后如何检索宽度和高度属性transform rotate 45deg 比如 旋转后 11x11 的正方形变成 17x17 Chrome 结果 但 javascript 仍然返回原始宽度 高度 10x10 我如何获得这个 17x17 您可
  • Powershell Golf:下一个工作日

    如何使用 powershell 查找下一个工作日 好吧 我的手机允许我设置哪些日子是工作日 但 Windows NET 不允许 所以我假设是周一到周五 注意 由于问题包括 高尔夫 我正在打高尔夫球 即尝试为脚本使用尽可能少的字节 结果代码不
  • lapply 适用于数组还是单个元素?

    我对 lapply 是否适用于列表或向量有点困惑 请参阅下面的两个示例 这里 均值函数应用于数字数组 即 1 到 5 x list a 1 5 b rnorm 10 x a 1 1 2 3 4 5 b 1 0 57544290 0 5103
  • C 从管道块读取直到子进程终止

    父进程创建 N 个子进程 每个子进程都用 exec 替换自己 父进程和 exec 之间通过一系列管道进行通信 int pipelinefd N 2 The exec使用以下命令写入管道 char msg 50 sprintf msg tse