Multithreading Pthread程序在Pthread#u join执行之前挂起,可以';我不明白为什么

Multithreading Pthread程序在Pthread#u join执行之前挂起,可以';我不明白为什么,multithreading,pthreads,Multithreading,Pthreads,我尝试使用pthreads做一个相当简单的搜索,将文本文件分成5列,5个线程分别执行搜索。在此之后,将进行合并,以确定输入是否与文本文件中的任何单个条目匹配。然而,当我运行它时,它似乎挂起了。我想我有一些不同的竞争条件,但是用DDD调试还没有产生任何结果 我认为我正在正确地创建和连接pthread,但我不确定是否正确地使用了互斥体 搜索函数在给定列中创建一个唯一值的链接列表,然后创建一个位掩码,其中包含找到该值的标记。无论如何,如果我运行一个标准的线性搜索,我得到的测试数据结果比线程多7个,我认

我尝试使用pthreads做一个相当简单的搜索,将文本文件分成5列,5个线程分别执行搜索。在此之后,将进行合并,以确定输入是否与文本文件中的任何单个条目匹配。然而,当我运行它时,它似乎挂起了。我想我有一些不同的竞争条件,但是用DDD调试还没有产生任何结果

我认为我正在正确地创建和连接pthread,但我不确定是否正确地使用了互斥体

搜索函数在给定列中创建一个唯一值的链接列表,然后创建一个位掩码,其中包含找到该值的标记。无论如何,如果我运行一个标准的线性搜索,我得到的测试数据结果比线程多7个,我认为这意味着搜索或合并线程失败了。将批处理大小从我的数据集的10%块减少到一次1或2个值会增加匹配的数量,但我仍然错过了正确的总数

如果有人知道为什么程序在完成之前挂起(可能是由于搜索或合并线程),我将非常感谢您的帮助

为了简洁起见,我省略了大约一半的代码,但是如果有帮助的话,我可以发布更多

void * search(void* pthread_arg){
  search_thread_param * myParams = (search_thread_param*) pthread_arg;
  int k=0; // how many searches have been done so far
  int m;
  while (k<NUM_PACKETS){
    pthread_mutex_lock(&mutex);
    if(n !=0){
      pthread_cond_wait(&search_cv, &mutex);  // mege is in progress, go to sleep
    }
    pthread_mutex_unlock(&mutex);     // release th lock so the other search threads can acquire it

    for (m =0; m < BATCH; m++)
      myParams->buffer[m] = mySearchFunction(myParams->packet_field[k+m], myParams->rule_field, unique_no[myParams->thread_id]);  // given a value, return its BV

    k=k+m;
    pthread_mutex_lock(&mutex);
    if (n==NUM_FIELDS-1) // this search thread is the only active one
      {
    n++;

    pthread_mutex_unlock(&mutex);   
    pthread_cond_signal(&merge_cv); // wake up merge thread
      } 
    else{  // not the last one goes to sleep
      n++;
      pthread_mutex_unlock(&mutex); 
    }   
  } 
  return NULL;
}

void merge_function(unsigned long b0,unsigned long b1,unsigned long b2,unsigned long b3,unsigned long b4){
  unsigned long final_BV;

  final_BV = b0 & b1 & b2 & b3 & b4;

  if( final_BV )
  int counter = 0;
    while(final_BV){
      counter++;
      final_BV = final_BV >> 1; //bit shift 
    }
    if( counter)
      printf("matched rule %i\n", counter);

}
void * merge (void* pthread_arg){
  merge_thread_param * myParams = (merge_thread_param*) pthread_arg;
  int k=0; // how many merges have been done so far
  int m;

  pthread_mutex_lock(&mutex);
  if (n<NUM_FIELDS) // the first batch is not ready
    pthread_cond_wait(&merge_cv, &mutex);    // go to sleep

  while (k<NUM_PACKETS){
    for (m =0; m < BATCH; m++){
      merge_function(myParams->buffer[0][m],myParams->buffer[1][m],myParams->buffer[2][m],myParams->buffer[3][m],myParams->buffer[4][m]);
    }
      printf("Merge thread: finish merging one batch\n");   
      k=k+m;
      n = 0; //ready to wake up all search threads
      if(k ==NUM_PACKETS){  // the program is over
    pthread_mutex_unlock(&mutex);   
    printf("Merge thread:  I am done, found %i results, compared to %i linear search  n = %i\n",res,lin,n);
    return NULL;
      }
      else  {
    pthread_cond_broadcast(&search_cv);
    pthread_mutex_unlock(&mutex);
    pthread_cond_wait(&merge_cv, &mutex);    // go to sleep
      }  
  }     
  return NULL;
}

int main () {
///////setup info omitted for brevity
  // create search threads
  for (i=0; i< NUM_FIELDS; i++)
    if(pthread_create(&s_thread[i], &attr, search, (void*) &stp[i])!=0){printf("Creating Thread failed!\n");}

  // create merge thread        
  if(pthread_create(&m_thread, &attr, merge, (void*) &mtp)!=0){printf("Creating Thread failed!\n");}

  // join the threads
    for (i=0; i<NUM_FIELDS; i++)
    if (pthread_join(s_thread[i], NULL)==0){printf("joined thread %i\n",i);}
    else{printf("Joining thread %i failed!\n",i);}

  if (pthread_join(m_thread, NULL)!=0){printf("joined merge thread");}
  else{printf("Joining thread failed!\n");}     

  pthread_attr_destroy(&attr);
  pthread_mutex_destroy(&mutex);
  pthread_cond_destroy(&search_cv);
  pthread_cond_destroy(&merge_cv);      
  //free dat memory
  printf("finished joining all the threads");
  fflush(stdout);
  return 0;
}
void*搜索(void*pthread_arg){
search_thread_param*myParams=(search_thread_param*)pthread_arg;
int k=0;//到目前为止已经进行了多少次搜索
int m;
而(kbuffer[m]=mySearchFunction(myParams->packet_field[k+m],myParams->rule_field,unique_no[myParams->thread_id]);//给定一个值,返回其BV
k=k+m;
pthread_mutex_lock(&mutex);
if(n==NUM\u FIELDS-1)//此搜索线程是唯一活动的线程
{
n++;
pthread_mutex_unlock(&mutex);
pthread_cond_signal(&merge_cv);//唤醒合并线程
} 
否则最后一个就不会睡觉了
n++;
pthread_mutex_unlock(&mutex);
}   
} 
返回NULL;
}
void merge_函数(无符号长b0、无符号长b1、无符号长b2、无符号长b3、无符号长b4){
未签名的长最终字母;
最终版本=b0&b1&b2&b3&b4;
if(最终版本)
int计数器=0;
while(最终版本){
计数器++;
final_BV=final_BV>>1;//位移位
}
如果(计数器)
printf(“匹配规则%i\n”,计数器);
}
void*merge(void*pthread_arg){
merge_thread_param*myParams=(merge_thread_param*)pthread_arg;
int k=0;//到目前为止已经完成了多少次合并
int m;
pthread_mutex_lock(&mutex);
如果(nbuffer[1][m],myParams->buffer[2][m],myParams->buffer[3][m],myParams->buffer[4][m]);
}
printf(“合并线程:完成合并一批\n”);
k=k+m;
n=0;//准备好唤醒所有搜索线程了吗
如果(k==NUM_PACKETS){//程序结束
pthread_mutex_unlock(&mutex);
printf(“合并线程:我完成了,找到了%I个结果,与%I线性搜索n=%I\n”,res,lin,n相比);
返回NULL;
}
否则{
pthread_cond_广播(&search_cv);
pthread_mutex_unlock(&mutex);
pthread_cond_wait(&merge_cv,&mutex);//进入睡眠状态
}  
}     
返回NULL;
}
int main(){
///////为简洁起见,省略了设置信息
//创建搜索线程
对于(i=0;i对于(i=0;i问题在于,确定是否在合并线程中设置pthread_cond_wait的检查出错,导致合并线程在搜索线程之前执行。这意味着合并线程在搜索线程完成生成结果之前完成。然后,搜索线程向不存在的线程发出信号and进入睡眠状态。它从未加入,因为它从未完成。所以,你有了它