gpt4 book ai didi

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

转载 作者:太空宇宙 更新时间:2023-11-04 03:00:35 26 4
gpt4 key购买 nike

父进程创建了 N 个子进程,每个子进程都用 exec 替换了自己。 parent 和 exec 之间通过管道数组进行通信 (int pipefd[N][2];)

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]);
}

现在的问题是,只有在子进程终止后,读取才会解除阻塞并打印缓冲区。我想要做的是在 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 来跟踪 fork ),以便您可以验证什么实际上是从管道写入/读取。

我怀疑在这种情况下,什么都不是 child 写的!这是因为您使用的 stdio 层 (printf()) 检查它是写入终端还是写入其他任何东西。在终端的情况下,它在每个换行符后刷新输出,但在其他情况下,它仅在写入大数据 block (GNU 系统上为 8KiB)后刷新。尝试在 printf() 之后使用 fflush() 手动刷新输出。如果有帮助,您可以使用 setvbuf() 调整 stdout 缓冲模式。

关于C 从管道 block 读取直到子进程终止,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12657430/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com