2012-07-12 95 views
0

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

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()); 
} 
+0

我有一个额外的问题。我附加的代码只能识别未标记的轮廓,只对1和零标记的蒙版执行。我的输入蒙版图像实际上标记为每个轮廓的1,2,3,4 ....例如,第一个轮廓标记为1,第二个轮廓标记为2,所有轮廓仅为1。如何修改我的代码,以便我可以根据标记的图像分别分离每个轮廓。示例contour1是一个单独的图像,contour2是另一个单独的图像。 – user1373805 2012-07-16 21:38:19

回答

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]; 

创建一个本地未初始化的二维int数组statistics_ratio,什么都不做吧,然后将其分配给另一个本地创建的对象的成员。这看起来没有意义,另一个pthread实例tid3的声明也是如此。

这并不重要,因为没有其他人可以看到该线程,但是如果没有首先解锁互斥体,则您从此函数内部返回,如果pImg == NULL

很难看出为什么你的代码不起作用,或者它意味着什么,但是上面强调的事情可能会有所帮助。你正在你的线程函数中创建很多没有被使用的局部变量。我不确定你是否需要其中的一些来代替全局 - 尤其是互斥锁(如果确实需要它)。

+0

感谢所有的回应。我有一个额外的问题。我附加的代码只能识别未标记的轮廓,只对1和零标记的蒙版执行。我的输入蒙版图像实际上标记为每个轮廓的1,2,3,4 ....例如,第一个轮廓标记为1,第二个轮廓标记为2,所有轮廓仅为1。如何修改我的代码,以便我可以根据标记的图像分别分离每个轮廓。示例contour1是一个单独的图像,contour2是另一个单独的图像。 – user1373805 2012-07-16 21:37:55

+0

第二个答案比第一个更集中。但两者在不同的观点上都是分别正确的。感谢这两个。 – user1373805 2012-09-01 20:21:10

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?这就是为什么在创建它之后加入线程的原因--结构保持稳定,因为循环会阻塞直到线程完成。

改变环路看起来是这样的:。

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()函数分配的内存块:

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

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

除了无谓的使用互斥数学家1975提到的handleObject()线程函数(http://stackoverflow.com/a/11460092/12711)。

线程函数中的代码(复制或试图在本地复制数据,互斥量)的一小段似乎是尝试修复问题而不真正理解问题所在。我认为您真的需要了解各种数据的存在位置,如何复制它(而不是仅仅复制一个指针),以及如何管理数据的所有权。