如何在叉子后用键盘引入字符串

时间:2015-06-08 20:07:36

标签: c concurrency process signals scanf

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

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

答案 0 :(得分:1)

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

我已经使用一个简单的示例进行了测试并且正常工作(只需通过 fscanf 更改 scanf )。如果那是你的问题,请告诉我。