【问题标题】:Difficulty in using the pipe, using multithreading管道使用困难,使用多线程
【发布时间】:2021-09-13 10:41:36
【问题描述】:

我声明我最近一直在使用C语言,所以我不是很了解...... 我正在制作一个脚本,它使用 3 个并行运行的线程,因此同时查找素数,直到作为参数传递的数字 n。到目前为止,我相信我没有犯任何错误,至少我认为,如果没有,请向我报告。然后我必须将这些质数存储在一个存储器文件(这是一个名为 memorizer.c 的简单文件)中,每行一个,按升序排列。存储必须由完全独立于线程的另一个进程完成。 我遇到的问题是创建管道时出错。 不知道其他的好不好。。。。 你能帮帮我吗?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>


pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int num, n ; 
int fp ; 



void *find_prime_number (void* name){

int *th  = (int *) name;

while(num <= n ){

int check = 0; 

for(int i=2 ;i<=num/2; i++ ){
if(num<=n){
   if (num % i==0 ){
 printf("Thread %d : %d , IS NOT a prime number \n", *th, num); 
 check=1; 
 break; 
  }
}


else{

pthread_mutex_unlock(&mutex);
return 0 ; 
     }
 }

if (num<=n){
if(check == 0){
    
printf("Tread %d : %d  IS a prime number  , sent to memorizer\n", 
*th, num); 
write (fp, &num , sizeof(num)); 

  }
}

  else {
pthread_mutex_unlock(&mutex); 
return 0 ; 

}


if (num <= n){
pthread_mutex_lock(&mutex);
num++; 
}

 pthread_mutex_unlock(&mutex); 

  }   
}

int main(int argc , char *argv[]){

char *fifo = "memorizer.c" ;

if (argc != 2 ){
printf("error in entering parameters \n ");
return -1 ; 
}

int error ; 
n= atoi(argv[1]); 
pthread_t t1 , t2 , t3 ; 
pthread_t *calc_arr[3] = { &t1 , &t2 , &t3 } ;  

if (error = mkfifo( fifo , 0666)== -1){

printf("Error pipe fifo \n"); 
return -1; 
}

if ((fp = open(fifo, O_WRONLY))==-1 ){
printf("Error opening pipe\n");
return -1 ; 
}




int thread[]= {1,2,3}; 

for(int i = 0; i<3 ; i++ ){
if(error = pthread_create(calc_arr[i], NULL,find_prime_number,&thread[i]) != 0  ){

perror("Errore creation thread");
exit(1);

   }
 }


for (int i = 0; i < 3 ; i++){

if (error=pthread_join(*calc_arr[i], NULL )!= 0  ){

perror("Error join thread ");
exit(1);
    }
 }

close(fp);
printf("Threads termination "); 
return 0 ; 

}

【问题讨论】:

  • edit您的问题一致地重新缩进代码。这将使它更容易阅读和理解。
  • char *fifo = "memorizer.c" 缺少; - 这甚至可以为您编译吗?
  • 不,它总是在创建管道时给我一个错误
  • @LucaLucazzo 如果你不能编译你的代码,你就不能运行你的程序。
  • 您看到的所有发布的代码都有一致的间距和缩进是有原因的:这使得代码更易于阅读和理解。像您发布的那样不一致的格式,到处都是大括号,随机插入空行,不同级别的缩进,所有这些都使代码几乎无法阅读。花点时间使您的代码具有可读性,并具有一致的格式。当您可以看到正在执行的操作时,编写可工作的多线程代码已经够难的了。你用令人困惑的格式挖了你的眼睛,这可能导致你无法让它工作

标签: c multithreading pipe


【解决方案1】:

在创建管道时总是给我一个错误

你错了;并不总是有错误,事实上,在创建管道时没有错误。你应该戒掉那些掩盖真正错误原因的无意义的错误信息; #include &lt;errno.h&gt; 和改变

printf("Error pipe fifo \n"); 

    perror(fifo);
    if (errno != EEXIST)

您会看到只有在管道已经创建时才会出现错误:

memorizer.c: File exists

由于这实际上不是错误,if 用于跳过 return 语句。

然后,我不会在主线程中打开用于写入的管道,因为这会阻塞,直到它也被打开以进行读取。我宁愿打开它以便在每个创建的线程中写入,并在创建其他线程后在主线程中读取。

char *fifo = "memorizer.c";

void *find_prime_number(void *name)
{
  if ((fp = open(fifo, O_WRONLY)) == -1)
  {
    perror(fifo);
    pthread_exit((void *)-1);
  }
  …
int main(int argc, char *argv[])
{
  …
  if ((fp = open(fifo, O_RDONLY)) == -1)
  {
    perror(fifo);
    return 1;
  }
  …

我的锁肯定有问题,解锁很明显....

确实是锁定出了问题。 num 的访问和修改必须是独占的。仅在一个地方执行此操作;将while(num &lt;= n ){ 更改为:

  int mynum;
  while (pthread_mutex_lock(&mutex), mynum = num++,
       pthread_mutex_unlock(&mutex), mynum <= n)
  {

在线程函数中别处使用全局num,并删除所有其他锁定和解锁调用。

【讨论】:

  • 非常感谢您的解释。所以基本上如果我保持打开状态(fifo,O_WRONLY),就像你告诉我的那样,我必须在发送程序运行的同时运行阅读程序。所以我必须以这样一种方式来实现存储器,它可以从管道中读取传入的数据,对吗?所以首先我运行主文件,然后从另一个终端运行存储器,它会显示素数,对吗?
  • 我在上面回复了
  • 我已经更新了,你也可以看看。
  • 谢谢,现在我更清楚了。我只是想从评估中排除零,因为它在技术上不是质数,我不认为我正在造成这种损害。数字 1 也是如此,它不是素数。
  • 是的,我确实是这么做的,非常感谢您的帮助。
猜你喜欢
  • 2013-09-05
  • 1970-01-01
  • 1970-01-01
  • 2013-11-03
  • 2021-03-30
  • 2021-07-06
  • 2012-03-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多