叉子后如何通过键盘在孩子中引入字符串
Posted
技术标签:
【中文标题】叉子后如何通过键盘在孩子中引入字符串【英文标题】:How to introduce string by keyboard in child after fork 【发布时间】:2015-06-08 20:07:35 【问题描述】:我正在练习 C 中的并发性,我编写了一个小而简单的程序,其中父进程创建了两个子进程,发送者和接收者。 发送者将从标准输入中读取一个字符串,然后以某种方式将其发送给接收者(不相关)。
这里真正的问题是,当我运行程序时,它执行分叉,两个孩子将出生,发件人应该等待一个字符串作为输入,但我找不到使用终端插入任何内容的方法. 该程序似乎挂在scanf上,但我找不到引入任何输入的方法。终端,一旦程序启动,就不允许我插入任何东西。
我使用的是 Xcode 6.3.2
#include <stdio.h>
#include <sys/wait.h>
#include <signal.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#define FILE_NAME "conteggio"
#define MAX_CHAR 25
void receiver();
void sender();
void receiver_operation();
void sender_operation();
void to_maiusc(char s[], char* r);
int readline(int fd, char *str);
void nothing()
typedef enum FALSE, TRUE boolean;
int sender_pid, receiver_pid;
int main(int argc, const char * argv[])
FILE *f_in;
int status, num, sender_pid, receiver_pid;
// create the two childs
if ( (sender_pid = fork()) != 0 )
// I'm the father
if ( (receiver_pid = fork()) != 0 )
// wait until the two processes return
wait(&status);
wait(&status);
// read the number of interactions
if ( (f_in = fopen(FILE_NAME, "rb")) != NULL )
fread(&num, sizeof(int), 1, f_in);
printf("Il numero di interazioni è: %d", num);
fclose(f_in);
return 0;
else
// Sono il receiver
receiver_operation();
else
// sono il sender
sender_operation();
int readline(int fd, char *str)
char c = '\0';
int i = 0;
while (c != '\n')
read(fd, &c, 1);
str[i] = c; i++;
str[i] = '\0';
return i;
void sender_operation()
FILE *fin;
int r_pid, count = 0;
char stringa[MAX_CHAR+1];
boolean finito = FALSE;
signal(SIGUSR1, nothing);
// aspetto che il receiver scriva sul file il pid e lo apro
pause();
if ( (fin = fopen("pid", "rb")) == NULL )
printf("Impossibile aprire file 'pid'.\n");
return;
// leggo il pid
fread(&r_pid, sizeof(int), 1, fin);
fclose(fin);
while (!finito)
// leggo una stringa da tastiera
kill(0, SIGSTOP);
printf("Insert a string: ");
scanf("%s", stringa);
// controllo se è 'end'
if ( strcmp(stringa, "end") == 0 )
finito = TRUE;
// scrivo su file
if ( (fin = fopen("stringa.txt", "w")) == NULL )
printf("Impossibile aprire file 'stringa.txt'.\n");
fprintf(fin, "%s", stringa);
fclose(fin);
// segnalo al receiver che il file e' pronto
kill(r_pid, SIGUSR1);
// aspetto il risultato
pause();
// leggo il risultato
if ( (fin = fopen("stringa.txt", "r")) == NULL )
printf("Impossibile aprire file 'stringa.txt'.\n");
return;
fscanf(fin, "%s", stringa);
// stampo il risultato
printf("Stringa processata: %s", stringa);
fclose(fin);
// incremento numero iterazioni
count++;
// stampo su un file il numero di iterazioni
if ( (fin = fopen(FILE_NAME, "wb")) == NULL)
printf("Impossibile creare il file %s\n", FILE_NAME);
return;
fwrite(&count, sizeof(int), 1, fin);
fclose(fin);
exit(0);
void receiver_operation()
FILE *fout;
int pid;
boolean finito = FALSE;
char stringa[MAX_CHAR+1], result[MAX_CHAR+1];
signal(SIGUSR1, nothing);
// scrivo il mio pid su un file
if ( (fout = fopen("pid", "wb")) == NULL )
printf("Impossibile creare il file 'pid'\n");
return;
pid = getpid();
fwrite(&pid, sizeof(int), 1, fout);
fclose(fout);
// segnalo il file pronto
kill(sender_pid, SIGUSR1);
while (!finito)
// ora aspetto che il sender scriva una stringa sul file 'stringa.txt'
pause();
// leggo la stringa da processare
if ( (fout = fopen("stringa.txt", "r")) == NULL )
printf("Impossibile aprire il file 'stringa.txt'\n");
return;
fscanf(fout, "%s", stringa);
fclose(fout);
if ( strcmp(stringa, "end") == 0 )
finito = TRUE;
// processo la stringa
to_maiusc(stringa, result);
// scrivo sul file il risultato
if ( (fout = fopen("stringa.txt", "w")) == NULL )
printf("Impossibile scrivere il risultato su 'stringa.txt'\n");
return;
fprintf(fout, "%s", result);
fclose(fout);
// segnalo il risultato pronto
kill(sender_pid, SIGUSR1);
void to_maiusc(char s[], char* r)
int i;
r = malloc( sizeof(char) * strlen(s) +1);
// converto la stringa da maiuscola a minuscola
for(i=0; i<strlen(s); i++)
r[i] = toupper(s[i]);
return;
有人知道吗?
【问题讨论】:
【参考方案1】:让我看看我是否正确,您的问题是子进程无法读取stdin
,对吗?你可以使用fscanf(stdin, stringa);
我已经用一个简单的例子进行了测试并且工作了(只是将你的 scanf 更改为 fscanf)。让我知道这是否是您的问题。
【讨论】:
我很高兴地说“你是对的”。这解决了我的问题。有谁知道为什么在这里使用 scanf 会带来问题? 我不是 100% 确定,但这可能与文件描述符有关。当您的子进程使用 scanf 时,它会尝试读取作为管道的标准输入。因此,有必要指定标准输入以避免这种行为。但同样,我只是在猜测。以上是关于叉子后如何通过键盘在孩子中引入字符串的主要内容,如果未能解决你的问题,请参考以下文章