稍微复杂的线程同步 [英] Slightly complicated thread synchronization

查看:108
本文介绍了稍微复杂的线程同步的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

背景信息:
我试图创建一个C程序,让我通过几个不同的文件(源2)的最大素数搜索。该方案是多线程,以加快这一进程。在这个项目中我$ P $通过具有螺纹pferring计算时间,而浪费的时间等待,直到所有的线程都分配globalLargestPrime。

Background info: I am Trying to create a C program that allows me to search through several different files (2 in the source) for the largest prime number. The program is multi-threaded to speed up the process. In this program I am preferring computational time rather that wasted time by having a the threads wait until all of the threads have assigned globalLargestPrime.

问题:
我相信,在我的程序或者某个地方的ID没有被作为参数传递正确,或者在某个地方我的程序饿死一个线程。

The problem: I believe that in my program somewhere either the id is not being passed as a parameter properly, or that somewhere my program starves one of the threads.

在怪异的一部分:
当我运行我的程序将运行并完成,但有时它只会催生一个线程,因此它不会通过两个文本文件中搜索。而其他时候将产生两个线程,并从两个文本文件阅读

The weird part: When I run my program it will run and finish but sometimes it will only spawn one thread, therefore it will not search through both text files. and other times it will spawn both threads and read from both text files

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <pthread.h>
#include <time.h>

pthread_mutex_t mutex;
pthread_cond_t monitor[2];
int globalLargestPrime = 0;
const int numThreads = 2;
FILE *fIN[2];

typedef enum{
  FREE,
  IN_USE
}lrgstPrm;
lrgstPrm monLargestPrime;//create struct

int timed(){
 return time(NULL);
}

int ChkPrim(int n){
  int i;
  int isPrime = 0;
  int root = sqrt(n);
  for(i=2; i<root; i++){
        if(n % i == 0)
          isPrime = 1;
        else
          isPrime = 0;
     }
  return isPrime;
}

void *calc_sqrt(void *threadID){//Create Threads
  int index, currentNum;
  int localLargestPrime = 0;
  int id = *(int *)threadID;
  int thousandsOfTimes = 0;
  //FILE *fIN = fopen("data.txt", "r");

  //printf(PTHREAD_MUTEX_ERRORCHECK);
  //Calculate some sqrts
  while(!feof(fIN[id])){
  for(index = 0; index < 1000; index++ )
  {//Check every thousand times
    fscanf(fIN[id], "%d\n", &currentNum);
    if(currentNum>localLargestPrime)
      if(ChkPrim(currentNum) == 1)
        localLargestPrime = currentNum;
  }

    pthread_mutex_lock(&mutex);

    thousandsOfTimes++;

    while(monLargestPrime == IN_USE)
    pthread_cond_wait(&monitor[id], &mutex);//wait untill mutex is unlocked
    monLargestPrime = IN_USE;
    //Critical Zone
    printf("Entering Critical Zone My ID: %d\n",id);
    if(localLargestPrime > globalLargestPrime)//Check for largest num
      globalLargestPrime = localLargestPrime;
    else
      localLargestPrime = globalLargestPrime;

    for(index = 0; index < numThreads; index++)
      if(index != id)
        pthread_cond_signal(&monitor[id]);//signal all threads that mutex is unlocked
    monLargestPrime = FREE;
    printf("Exiting Critical Zone My ID: %d\n",id);
    pthread_mutex_unlock(&mutex);
 //   printf("done searching thousand times %d My ID: %d\n",thousandsOfTimes, id);
  }
}

void createText(){
  FILE *fOUT = fopen("data.txt", "w");
  int i;
  srand(time(NULL));
  for(i=0; i<10000; i++)
  fprintf(fOUT, "%d\n",rand()%5000);
  fclose(fOUT);
}


int main(){
   printf("This is before creating threads\n");
  int index, timeDiff;
  pthread_t threads[2];
  pthread_mutex_init(&mutex, NULL);
  for(index = 0; index < numThreads; index++)
    pthread_cond_init(&monitor[index], NULL);
  fIN[0] = fopen("data0.txt","r");
  fIN[1] = fopen("data1.txt","r");

  timeDiff = time(NULL);
  //createText();

  for(index = 0; index < numThreads; index++){
    //int *id = malloc(1);
    //*id = index;
    pthread_create(&threads[index],NULL,calc_sqrt,&index);
  }
  for(index = 0; index < numThreads; index++)
    pthread_join(threads[index],NULL);
  printf("This is after creating threads");

  timeDiff = timed() - timeDiff;

  /*Destroy the mutexes & conditional signals*/
  pthread_mutex_destroy(&mutex);
  pthread_cond_destroy(&monitor[0]);
  pthread_cond_destroy(&monitor[1]);


printf("This is the Time %d\n", timeDiff);
printf("This is the Largest Prime Number: %d", globalLargestPrime);
return 0;
}

如果任何人都可以请帮我在这个问题上这将是AP preciated一些有识之士

If anyone Could please give me some insight on the issue it will be appreciated

感谢

推荐答案

您正在传递同一个局部变量线程的地址。由于该变量为每个线程更新被创建,当一个线程启动时,它可能会读取的目标用户不同的线程的值:

You're passing in the address of the same local variable to the threads. Since the variable is updated as each thread is created, when a thread starts it will likely read a value that's intended for a different thread:

pthread_create(&threads[index],NULL,calc_sqrt,&index)
                                              ^^^^^^

你最终得到的是多线程使用相同的 FILE *阅读

既然你传递一个简单的诠释,可以直接传递值作为参数螺纹:

Since you're passing in a simple int you can pass the value directly as the thread parameter:

pthread_create(&threads[index],NULL,calc_sqrt,(void*)index)

然后在线程中获得的价值,像这样:

Then in the thread get the value like so:

int id = (int)threadID;

有没有需要的条件变量在code。在所有的(虽然再次 - 我不知道这是造成问题)。你的条件变量跟踪 globalLargestPrime 是否在另一个线程或不使用。巧合的是,互斥做同样的事情!尝试:

There's no need for the condition variable at all in your code (though again - I'm not sure it's causing a problem). Your condition variable tracks whether globalLargestPrime is in use by another thread or not. Coincidentally, the mutex does the same thing! try:

pthread_mutex_lock(&mutex);

thousandsOfTimes++;     // not sure why this local variable even exists, 
                        //  much less is in a critical section

//Critical Zone
printf("Entering Critical Zone My ID: %d\n",id);
if(localLargestPrime > globalLargestPrime)//Check for largest num
  globalLargestPrime = localLargestPrime;
else
  localLargestPrime = globalLargestPrime;   // again, not sure why this is here...

printf("Exiting Critical Zone My ID: %d\n",id);
pthread_mutex_unlock(&mutex);

另外,你的code使用检查 EOF 的反模式读取文件之前:

Also, your code uses the antipattern of checking for EOF before reading the file:

while (!feof(somefile)) {
    // whatever...
}

这是不对的,但我想可能是在这种情况下一个无害的错误。参见:

which is wrong, though I think might be a harmless error in this instance. See:

  • Common C Programming Errors: Using feof() incorrectly
  • "while( !feof( file ) )" is always wrong

这篇关于稍微复杂的线程同步的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆