2013-02-23 72 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