2012-07-12 94 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)。

線程函數中的代碼(複製或試圖在本地複製數據,互斥量)的一小段似乎是嘗試修復問題而不真正理解問題所在。我認爲您真的需要了解各種數據的存在位置,如何複製它(而不是僅僅複製一個指針),以及如何管理數據的所有權。