2

割り当てがあり、行き詰まっており、どこに問題があるのか​​ わかりませんが、1つのスレッドを使用してファイルから2つの数値を取得し、その数値を画面に出力し、別のスレッドがそれらに2つの数値を追加して、それらを画面に印刷します。これが私がこれまでに持っているものですが、適切に機能させることができないようです。どんな助けでも大歓迎です。 指摘しておきたいのは、ミューテックスとセマフォを使用せずにこれを行う必要があるということです。

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

typedef struct
{
     int a;
     int b;
} pair_t;

FILE *f;

static void * reader(void *data){
    pair_t *d = (pair_t *)data;
    sigset_t catch;
    int flag;

    sigemptyset(&catch);

    sigaddset(&catch, SIGUSR1);

    while(!feof(f)){
        sigwait(&catch, &flag);
        fscanf(f,"%d", &d->a);
        fscanf(f,"%d", &d->b);
        printf("Thread 1 submitting : %d %d", d->a, d->b);
        sleep(5);
    }
    return 0;
}

static void * calculator(void *data){
    pair_t *pa = (pair_t *)data;
    sigset_t catch;
    sigemptyset(&catch);
    sigaddset(&catch, SIGUSR1);
    int flag;

    while(1){
        sigwait(&catch, &flag);
        printf("Thread 2 calculated = %d\n",(pa->a + pa->b));
        sleep(5);
    }
    return 0;
}

int main(int argc, char *argv[]){
    f = fopen(argv[1],"r");
    if(f ==NULL){
        perror; 
    }
    if(f !=NULL){
        pair_t * p;

        sigset_t set;
        sigemptyset(&set);
        sigaddset(&set, SIGUSR1);

        pthread_t t1;
        pthread_t t2;

        pthread_sigmask(SIG_BLOCK, &set, NULL);
        pthread_create(&t1, NULL, reader, (void *)&p);
        pthread_create(&t2, NULL, calculator, (void *)&p);

        pthread_join(t1, NULL);
        printf("Goodbye from Thread One");
        pthread_join(t2, NULL);
        printf("Goodbye from Thread Two");

        pthread_exit(NULL); 
    }
    return 0;
}
4

1 に答える 1

1

私があなたの考えを正しく理解していれば、reader() に値を読み取ってから計算機に送信してもらいたいと思います。その場合、まず pthread_kill() を使用してリーダーから計算機にシグナルを送信する必要があります。そのためには、読者に t2 が見えるようにする必要があります。
計算の終了に関する計算機からのバックシグナルが必要ない場合は、リーダーから sigwait() を削除するだけです。それ以外の場合は、電卓から t1 に信号を送信して、計算が終了し、リーダーがファイルから値を読み続けることができることをリーダーに知らせる必要があります。
したがって、生産者と消費者の一般的なケースです。
以下のコードにいくつかのコメントがあります。

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

typedef struct
{
     int a;
     int b;
} pair_t;

FILE *f;

pthread_t t1; // must be global for pthread_kill()
pthread_t t2; // must be global for pthread_kill()

static void * reader(void *data){

    pair_t *d = (pair_t *)data;
    sigset_t catch;
    int flag;

    sigemptyset(&catch);        
    sigaddset(&catch, SIGUSR1); 

    while(!feof(f)){
        fscanf(f,"%d", &d->a);
        fscanf(f,"%d", &d->b);
        printf("Thread 1 submitting : %d %d", d->a, d->b);
        pthread_kill(t2, SIGUSR1); // tell calculator() to start computations
        sleep(5);               // this is not necessary if confirmation signal from
                                // calculator() is used
        //sigwait(&catch, &flag); // if you need confirmation from calculator()
                                // then this can be enabled
    }
    return 0;
}

static void * calculator(void *data){


    pair_t *pa = (pair_t *)data;
    sigset_t catch;
    sigemptyset(&catch);
    sigaddset(&catch, SIGUSR1);
    int flag;

    while(1){
        sigwait(&catch, &flag);
        printf("Thread 2 calculated = %d\n",(pa->a + pa->b));
        sleep(5); // don't need if confirmation below is used
        //pthread_kill(t1, SIGUSR1); // enable this if confirmation 
                                     // from calculator is necessary
    }
    return 0;
}

int main(int argc, char *argv[]){ 
    f = fopen(argv[1],"r");
    if(f ==NULL){
        perror;
        exit(1); // better to return here, because without file nothing to process
    }
    // no need to check, f != NULL already
    //if(f !=NULL){                     
        pair_t * p;

        sigset_t set;
        sigemptyset(&set);
        sigaddset(&set, SIGUSR1);

        //pthread_t t1;
        //pthread_t t2;

        pthread_sigmask(SIG_BLOCK, &set, NULL);
        pthread_create(&t1, NULL, reader, (void *)&p);
        pthread_create(&t2, NULL, calculator, (void *)&p);


        pthread_join(t1, NULL);
        printf("Goodbye from Thread One");
        pthread_join(t2, NULL);
        printf("Goodbye from Thread Two");

        pthread_exit(NULL); 

    //}
    return 0;
}

また、どちらもシグナルをブロックしないいくつかのスレッドを使用している場合、このシグナルをプロセスに送信すると、予期しない動作が発生します。それらのいずれかがシグナルをキャッチしてウェイクアップし、残りのスレッドがまだシグナルを待機している可能性があります。

于 2013-11-05T13:37:39.947 に答える