【发布时间】:2016-08-05 21:28:58
【问题描述】:
我应该编写一个程序来创建 2 个进程,用管道将它们连接起来,并在给定时间后结束这两个进程并终止。 其中一个程序将写入管道,另一个程序将从管道中读取并将其打印到 STDOUT。 首先将调用读取进程,然后将 pid 传递给第二个进程,因此它将向第一个进程发出 SIGUSR1 信号,告诉它读取。 出于某种原因,我从未在第一个进程的终端中看到输出, 此外,它甚至不打印行:“trying to exec1\n”,这是我为打印的进程调用“execlp”的地方。 这是 3 个程序的代码:
主程序:
#define STDERR 2
#define STDOUT 1
#define STDIN 0
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <signal.h>
#include <stdio.h>
void alarmHandler(int sig);
void systemError();
char * intToString(int num , char number[4]);
static pid_t processId1, processId2;
int main(int argc, char ** argv){
pid_t pid1, pid2;
sigset_t block_mask1;
struct sigaction exitSig;
sigfillset(&block_mask1);
exitSig.sa_handler = alarmHandler;
exitSig.sa_mask = block_mask1;
exitSig.sa_flags = 0;
sigaction(SIGALRM, &exitSig, NULL);
if (argc < 2){
systemError();
} else {
int x = atoi(argv[1]);
alarm(x);
}
int fields[2];
if (pipe(fields)){
systemError();
}
if ((pid1 = fork()) == 0){
printf("trying to exec1\n");
close(STDIN);
dup(fields[0]);
close(fields[0]);
close(fields[1]);
if(execlp("./ex2_inp", "./ex2_inp", NULL)){
systemError();
}
} else {
processId1 = pid1;
if ((pid2 = fork()) == 0){
char number[350];
printf("trying to exec2\n");
close(STDOUT);
dup(fields[1]);
close(fields[0]);
close(fields[1]);
char * pidString = intToString(processId1, number);
if(execlp("./ex2_upd","./ex2_upd",pidString, NULL)){
systemError();
}
} else{
processId2 = pid2;
}
}
close(fields[0]);
close(fields[1]);
pause();
return 1;
}
/***********************
* handler for alarm signal
*************************/
void alarmHandler(int sig){
kill(processId2, SIGINT);
kill(processId1, SIGINT);
exit(1);
}
/***********************
* turn pid to string
*************************/
char * intToString(int num , char number[350]){
sprintf(number, "%d", num);
return number;
}
ex2_inp:
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <signal.h>
#include <stdio.h>
void exitHandler(int sig);
void printHandler(int sig);
int main(int argc, char * argv[]){
sigset_t block_mask1, block_mask2;
struct sigaction exitSig, print;
sigfillset(&block_mask1);
sigfillset(&block_mask2);
exitSig.sa_handler = exitHandler;
print.sa_handler = printHandler;
print.sa_mask = block_mask2;
exitSig.sa_mask = block_mask1;
exitSig.sa_flags = 0;
print.sa_flags = 0;
sigaction(SIGINT, &exitSig, NULL);
sigaction(SIGUSR1, &print, NULL);
pause();
return 1;
}
void exitHandler(int sig){
printf("exiting1!\n");
close(1);
exit(1);
}
void printHandler(int sig){
char * buffer[80];
read(1, buffer, 80);
printf("%s", buffer);
}
ex2_upd:
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <signal.h>
#include <stdio.h>
void exitHandler(int sig);
int main(int argc, char * argv[]){
sigset_t block_mask1;
struct sigaction exitSig;
sigfillset(&block_mask1);
exitSig.sa_handler = exitHandler;
exitSig.sa_mask = block_mask1;
exitSig.sa_flags = 0;
sigaction(SIGINT, &exitSig, NULL);
printf("2's message\n");
kill(atoi(argv[1]), SIGUSR1);
pause();
return 1;
}
void exitHandler(int sig){
printf("exiting2!\n");
close(0);
exit(1);
}
谢谢
【问题讨论】:
-
在调用
printf之后和调用close之前尝试使用fflush(stdout);,以确保打印传递给printf的内容。 -
它没有帮助,我仍然没有看到我应该得到的“2's message\n”,由第一个进程打印
-
printf()不是异步安全的。此外,您打算发送信号的方式是竞争条件。该信号可能在接收者调用sigaction()之前发送。 -
有什么方法可以确保在那之前没有发送?谢谢
-
我会先学习 C 的基础知识,而不是多编程。
标签: c process pipe signals fork