2013-02-23 73 views
0

我最近開始研究pthreads並陷入了一個問題。所以,我有一個二叉樹拓撲結構,15個節點(0-> 14 nodeIDs),並且我爲節點3,4,5和6做了4個pthreads(不想爲例如創建更多)。因此,創建的每個線程都試圖到達其父節點來鎖定節點並在其中增加全局變量的值。爲此,我爲節點結構中的每個節點創建了一個互斥體,並使用了pthread_mutex_trylock條件 - 否則,我會讓它們做任何事情,例如完成而不是做工作或彼此不當行爲。因此,當我調用每個調用自己的線程的函數時,我的程序崩潰。代碼可以在下面看到。如果我將函數testExclusion的名稱更改爲testExclusion22,則工作正常,否則程序將繼續進行而不會停止。如果我的自助電話數量有限,則會發生同樣的情況。一個3次循環 - >見testFunction()。所以我的問題是,什麼是錯的?我有寫錯的東西嗎?或者這不被支持,如果是我該怎麼做?非常感謝!遞歸函數和pthreads

// main.c

// Threads_Extended 


#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <pthread.h> 

int globalVariable; 
pthread_mutex_t global; 

typedef struct node {  
    int value; 
    int nodeID; 
    struct node *parent; 

    pthread_mutex_t nodeMutex; 
} node_t ; 


void initialize_node(node_t *node,node_t *next, int nodeIdentity) 
{ 
    node->nodeID=nodeIdentity;  
    node->parent = next; 
    node->value=0; 
} 


void printingFunction(void){ 
    printf("This is for testing ONLY!"); 

    //for (int i=0; i<3; i++) { 
    printingFunction(); 
    //} 
} 


void testExclusion22(node_t *node, node_t *next) 
{ 
    int locked=0;  
    int locked2=0; 

    printf("I am thread %d and I am trying to lock node %d!\n", node->nodeID, next->nodeID); 

    while (locked!=1){ 
     if(pthread_mutex_trylock(&next->nodeMutex)==0){ 
      printf("I am thread %d and I am increasing the global value!\n", node->nodeID); 

      while(locked2!=1){ 
       if ((pthread_mutex_trylock(&global))==0){ 
        globalVariable++; 
        printf("Global variable's value is: %d!\n", globalVariable); 
        pthread_mutex_unlock(&global); 
        locked2=1; 
       } 
      } 

      printf("I am thread %d and I am releasing the node %d!\n", node->nodeID, next->nodeID); 
      pthread_mutex_unlock(&next->nodeMutex); 
      locked=1; 
     } 
     else 
      printf("I am thread %d and I was not able to lock next node %d!\n", node->nodeID, next->nodeID); 
} 

    printingFunction(); 
    // testExclusion(node, node->parent); 
} 

void testExclusion(node_t *node, node_t *next) 
{ 
    int locked=0; 
    int locked2=0; 

    printf("I am thread %d and I am trying to lock node %d!\n", node->nodeID, next->nodeID); 

    while (locked!=1){ 
     if(pthread_mutex_trylock(&next->nodeMutex)==0){ 
      printf("I am thread %d and I am increasing the global value!\n", node->nodeID); 

      while(locked2!=1){ 
       if ((pthread_mutex_trylock(&global))==0){ 
        globalVariable++; 
        printf("Global variable's value is: %d!\n", globalVariable); 
        pthread_mutex_unlock(&global); 
        locked2=1; 
       } 
      } 

      printf("I am thread %d and I am releasing the node %d!\n", node->nodeID, next->nodeID); 
      pthread_mutex_unlock(&next->nodeMutex); 
      locked=1; 
     } 
     else 
      printf("I am thread %d and I was not able to lock next node %d!\n", node->nodeID, next->nodeID); 
    } 

    testExclusion22(node, node->parent); 
    // testExclusion(node, node->parent); 
} 



void *PrintHello(void *node) 
{ 
    node_t *tempNode=node; 
    pthread_mutex_init(&global, NULL); 

    printf("Hello World! It's me, thread of node # %d!\n", (tempNode->nodeID)); 

    testExclusion(tempNode, tempNode->parent); 
    pthread_exit(NULL); 
} 


int main (int argc, char *argv[]) 
{ 

    node_t *nodes = malloc(15 * sizeof(node_t)); 

    int rc; 
    int simCounter; 

    int i; 
    int j=0; 
    int n=0; 

    globalVariable=0; 

    for (i=0; i<7; i++) { 
     if (i==0){ 
      initialize_node(&nodes[i],NULL,i); 
      printf("Node %d has been created! Node %d is the source root! \n\n", nodes[i].nodeID,nodes[i].nodeID); 
     } 
     else{ 
      if ((n%2)==0){ 
       initialize_node(&nodes[i],&nodes[j],i); 
       printf("Node %d has been created with Node %d as a parent! \n\n", nodes[i].nodeID,nodes[j].nodeID); 
       n++; 
      } 
      else 
      { 
       initialize_node(&nodes[i],&nodes[j],i); 
       printf("Node %d has been created with Node %d as a parent! \n\n", nodes[i].nodeID,nodes[j].nodeID); 
       j++; 
       n++; 
      } 
     } 
    } 

    simCounter=2; 

    for(i=0; i<7; i++) 
     pthread_mutex_init(&nodes[i].nodeMutex, NULL); 

    for (j=1; j<(simCounter+1); j++){ 
     pthread_t *threads = malloc(4 * sizeof(pthread_t)); 

     for(i=0; i<4; i++){ 
      printf("In main: creating thread %d\n", i); 
      nodes[i].nodeID=i; 
      rc = pthread_create(&threads[i], NULL, PrintHello, (void *)&nodes[i+3]); 
      if (rc){ 
       printf("ERROR; return code from pthread_create() is %d\n", rc); 
       exit(-1); 
      } 
      pthread_mutex_destroy(&nodes[i+3].nodeMutex); 
     } 
     for(i=0; i<4; i++) 
      pthread_join(threads[i], NULL); 

     printf("I am back in main!\n\n\n"); 

     free(threads); 
     pthread_mutex_destroy(&global); 
    } 

    free(nodes); 
    pthread_exit(NULL); 
} 
+0

在情況下,它並不明顯,在一個互斥體的嘗試鎖紡有點自我-defeating。仍然在看代碼的其餘部分,但是呃。 – WhozCraig 2013-02-23 23:18:54

+0

你爲什麼旋轉?爲什麼不直接用'while'循環調用'phtread_mutex_lock()'? – 2013-02-23 23:19:53

+0

我會*強烈*建議您刷新您的pthreads及其細微差別和用法的知識。當我看到諸如:'pthread_exit(NULL);'坐在**'main()'**的底部時,我開始懷疑。而且沒有必要旋轉這些循環中的任何*。 – WhozCraig 2013-02-23 23:53:49

回答

1

printingFunction()永遠自稱,沒有任何退出條件:

void printingFunction() { 
    printf("This is for testing ONLY!"); 
    printingFunction(); 
} 
+0

感謝您的評論。我已經改變了下面的功能,並放棄了所有其他功能。儘管如此。 – 2013-02-24 00:52:29

+0

因此,在iflock中使用if條件導致我的互斥鎖未被鎖定,但仍然使用中間代碼,導致內存錯誤,例如,空指針等等。我需要確保一個人在每個時間使用我的變量time.pthread_exit(null)在本教程主要原因的最後:https://computing.llnl.gov/tutorials/pthreads/#Mutexes 。 pthreads中的新功能,我必須從某個地方開始學習。 – 2013-02-24 01:04:14