gpt4 book ai didi

c - fork后如何通过键盘在子进程中引入字符串

转载 作者:行者123 更新时间:2023-11-30 15:19:21 24 4
gpt4 key购买 nike

我正在练习 C 语言的并发性,我编写了一个小而简单的程序,其中父进程创建两个子进程:发送者和接收者。发送者将从标准输入读取一个字符串,然后继续以某种方式将其发送给接收者(不相关)。

这里真正的问题是,当我运行程序时,它执行 fork,两个 child 将会出生,发送者应该等待一个字符串作为输入,但我找不到使用终端插入任何内容的方法。该程序似乎卡在 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;
}

有人知道吗?

最佳答案

让我看看我是否正确,您的问题是子进程无法读取 stdin,对吧?您可以使用fscanf(stdin, stringa);

我已经用一个简单的示例进行了测试并成功(只需将您的 scanf 更改为 fscanf)。让我知道这是否是您的问题。

关于c - fork后如何通过键盘在子进程中引入字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30718140/

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