我有一个任务,我被卡住了,我不知道问题出在哪里,但是我必须使用一个线程从文件中接收两个数字,在屏幕上打印数字,然后另一个线程将它们添加到两个数字在一起并在屏幕上打印。 这是我到目前为止所做的,但我似乎无法让它正常工作任何帮助将不胜感激。 我应该指出,我必须在不使用互斥锁和信号量的情况下执行此操作。
#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;
}
答案 0 :(得分: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;
}
另外,如果你使用两个都不阻塞某些信号的线程,那么将这个信号发送到一个进程会导致不可预测的行为 - 它们中的任何一个都可以捕获信号并唤醒,剩下的仍然在等待信号