首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >pthread并行处理

pthread并行处理
EN

Stack Overflow用户
提问于 2012-07-13 04:01:57
回答 2查看 1.2K关注 0票数 0

需要关于线程的紧急帮助:这里的目标是分离每个图像,并分离不同的轮廓,对于图像中的每个轮廓,它将调用handleobject线程。所以每个for循环都会调用handeobject线程。但是,对象索引变量需要在每个线程中传递。但只传递了objectndex的最后一个值,这是因为obj.objindx函数循环并替换了obj.objindx的值,只有objectndex的最后一个值被传递给所有线程。有没有办法在handleobject中传递每个objectindex值。如果我们取消对pthread_join(tidobjectIndex,NULL)的注释,代码就能正常运行;但它不会给出parralel程序

代码语言:javascript
复制
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());
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-07-13 04:27:04

此函数似乎有问题

代码语言:javascript
复制
void* handleObject(void *arg)

首先

代码语言:javascript
复制
    pthread_mutex_t lock=PTHREAD_MUTEX_INITIALIZER;
    pthread_mutex_lock(&lock);

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

代码语言:javascript
复制
    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,那么你可以从这个函数内部返回。

很难理解为什么你的代码不能工作,或者它的目的是什么,但也许上面突出显示的事情可能会有所帮助。你在你的线程函数中创建了很多没有被使用的局部变量。我不确定你是否需要其中一些是全局的--特别是互斥锁(如果你确实需要一个互斥锁的话)。

票数 2
EN

Stack Overflow用户

发布于 2012-07-15 03:23:32

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

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

代码语言:javascript
复制
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结构保持稳定,因为循环会阻塞,直到线程结束。

将循环更改为如下所示:

代码语言:javascript
复制
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()数据(即,线程创建代码创建并初始化数据块,然后将其所有权传递给线程)。

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

最后,还有其他几个明显的bug,比如立即覆盖由malloc()分配的块的指针:

代码语言:javascript
复制
obj.objectMaskImg1[objectIndex]=(IplImage *) malloc(sizeof(IplImage));
obj.objectMaskImg1[objectIndex]=objectMaskImg;

代码语言:javascript
复制
hndl=(handle *) malloc(sizeof(handle));
hndl=(handle*)arg;

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

线程函数中的相当一部分代码(复制或尝试在本地复制数据,互斥对象)似乎是在试图修复问题时抛出的东西,而实际上并不了解问题是什么。我认为您真的需要了解各种数据位于何处,如何复制它(而不仅仅是复制指向它的指针),以及如何管理数据的所有权。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11459706

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档