0

在线程上需要紧急帮助:这里的目标是 separtemask 将获取每个图像并分离不同的轮廓,并且对于图像中的每个轮廓,它将调用 handleobject 线程。所以每个for循环都会调用handeobject线程。但是,需要在每个线程中传递对象索引变量。但是只有 objectndex 的最后一个值被传递,这是因为 speratemask 函数循环并替换 obj.objindx 的值,并且只有 obj.objindx 的最后一个值被传递给所有线程。无论如何要在句柄对象中传递每个对象索引值。如果我们取消注释 pthread_join(tid[objectIndex],NULL); ,代码运行良好。但它不会给出并行程序

void separateMask(IplImage *maskImg)
{    
  for(r = contours; r != NULL; r = r->h_next)
  {
    cvSet(objectMaskImg, cvScalarAll(0), NULL);
    CvScalar externalColor = cvScalarAll(0xff);
    CvScalar holeColor = cvScalarAll(0x00);
    int maxLevel = -1; 
    int thinkness = CV_FILLED; 
    int lineType = 8; /* 8-connected */
    cvDrawContours(objectMaskImg, r, externalColor, holeColor, maxLevel, thinkness,lineType, cvPoint(0,0));;
    obj.objectMaskImg1[objectIndex]=(IplImage *) malloc(sizeof(IplImage));
    obj.objectMaskImg1[objectIndex]=objectMaskImg;
    obj.objindx=objectIndex;
    obj.intensityOut1=intensityOut;
    obj.tasOut1=tasOut;
    pthread_create(&tid[objectIndex],NULL,handleObject,(void *)&obj);
    //pthread_join(tid[objectIndex],NULL);
    printf("objectindx %d\n",obj.objindx);
    objectIndex++;

  }
  // cvReleaseImage(&objectMaskImg);
  //cvReleaseMemStorage(&storage);
  printf("Exitng Separatemask\n");

}


void* handleObject(void *arg)
{
  int i, j;
  handle *hndl;
  hndl=(handle *) malloc(sizeof(handle));
  hndl=(handle*)arg;
  pthread_mutex_t lock=PTHREAD_MUTEX_INITIALIZER;
  pthread_mutex_lock(&lock);
  IplImage *pImg;
  float statistics_ratio[3][9];
  pthread_t tid3;
  tas3 tas2;
  pImg = cvLoadImage("image.tif", CV_LOAD_IMAGE_ANYCOLOR | CV_LOAD_IMAGE_ANYDEPTH);
  if(pImg == NULL)
  {
    fprintf(stderr, "Fail to load image %s\n", "tiff file");
    return ;
  }
  tas2.pImg1=pImg;
  printf("tst%d\n",hndl->objindx);
  tas2.x=hndl->objindx;
  tas2.objectMaskImg1=hndl->objectMaskImg1[tas2.x];
  tas2.statistics_ratio[3][9]=statistics_ratio[3][9];
  double mean = average_intensity(pImg, tas2.objectMaskImg1); 
  int total = total_white(pImg, tas2.objectMaskImg1);
  pthread_mutex_unlock(&lock);

  printf("Exiting handle object thread_id %d\n\n", pthread_self());
}
4

2 回答 2

2

此功能似乎有问题

void* handleObject(void *arg)

首先

    pthread_mutex_t lock=PTHREAD_MUTEX_INITIALIZER;
    pthread_mutex_lock(&lock);

这是一个本地创建的互斥锁 - 但在线程函数中创建。所以你锁定它,但既然没有其他东西可以看到互斥锁,你为什么需要它???如果没有其他线程可以看到它,它不会提供同步功能。第二

    float statistics_ratio[3][9];
    pthread_t tid3;
    tas3 tas2;
    pImg = cvLoadImage("image.tif", CV_LOAD_IMAGE_ANYCOLOR | CV_LOAD_IMAGE_ANYDEPTH);
    if(pImg == NULL){
        fprintf(stderr, "Fail to load image %s\n", "tiff file");
        return ;
    }
    tas2.pImg1=pImg;
    printf("tst%d\n",hndl->objindx);
    tas2.x=hndl->objindx;
    tas2.objectMaskImg1=hndl->objectMaskImg1[tas2.x];
    tas2.statistics_ratio[3][9]=statistics_ratio[3][9];

您创建一个本地未初始化的 2d 浮点数组statistics_ratio,对其不做任何操作,然后将其分配给另一个本地创建的对象成员。这似乎没有意义,另一个 pthread 实例的声明也是如此tid3

这并不重要,因为没有其他东西可以看到线程,但是如果pImg == NULL没有首先解锁互斥锁,你会从这个函数内部返回。

很难看出您的代码为什么不起作用或它的用途是什么,但也许上面突出显示的事情可能会有所帮助。您在线程函数中创建了许多未使用的局部变量。我不确定你是否需要其中一些是全局的——尤其是互斥锁(如果你确实需要一个)。

于 2012-07-12T20:27:04.137 回答
1

我认为您最初的问题是您正在重用obj传递给创建线程的结构,因此您将遇到数据竞争,其中刚刚创建的线程将读取已被用于另一个线程的数据覆盖的信息。

创建线程的循环具有以下结构:

for(r = contours; r != NULL; r = r->h_next)
{
    // initialize obj with information for the thread
    // ...

    // create a thread and pass it a pointer to obj
    pthread_create(&tid[objectIndex],NULL,handleObject,(void *)&obj);

    // some other bookkeeping
}

由于您在下一次循环迭代时立即重新初始化 obj,谁知道线程函数将获取哪些数据?这就是为什么如果你在创建线程后加入线程,事情就会起作用的原因——obj结构保持稳定,因为循环阻塞直到线程完成。

将循环更改为如下所示:

for(r = contours; r != NULL; r = r->h_next)
{
    // instead of using `obj`, allocate a struct using malloc
    handle* threaddata = malloc(sizeof(handle); // note: I'm not sure if `handle` is the right type

    // initialize *threaddata with information for the thread
    // ...

    // create a thread and pass it the threaddata pointer
    pthread_create(&tid[objectIndex],NULL,handleObject,threaddata);

    // some other bookkeeping
}

然后free()线程函数中的数据用 with 完成后(即线程创建代码创建并初始化数据块,然后将其所有权传递给线程)。

请注意,这可能不像通常那样简单,因为看起来您的obj结构中已经包含一些每个线程的信息(objectMaskImg1元素看起来是一个数组,每个元素都用于单独的线程)。因此,您可能还需要对数据结构进行一些重构。

最后,还有其他几个彻底的错误,例如立即覆盖指向 malloc() 分配的块的指针:

obj.objectMaskImg1[objectIndex]=(IplImage *) malloc(sizeof(IplImage));
obj.objectMaskImg1[objectIndex]=objectMaskImg;

hndl=(handle *) malloc(sizeof(handle));
hndl=(handle*)arg;

除了handleObject()数学家1975(http://stackoverflow.com/a/11460092/12711)提到的线程函数中毫无意义地使用互斥锁之外。

A fair bit of the code in the thread function (copying or attempting to copy data locally, the mutex) appears to be stuff thrown in to try to fix problems without actually understanding what the problem is. I think you really need to get an understanding of where various data lives, how to copy it (as opposed to just copying a pointer to it), and how to manage the ownership of the data.

于 2012-07-14T19:23:32.193 回答