Reputation: 3
I recently started working on pthreads and stuck with a problem. So, I have a binary tree topology, 15 nodes (0->14 nodeIDs) and I 've made 4 pthreads for the nodes 3,4,5 and 6 (didn't want to create more for an e.g.). So, each thread created is trying to reach its parent node to lock the node and to increase the value of a global variable in there. To do this I've created a mutex for each node in the node structure and used pthread_mutex_trylock conditions- otherwise I had them do whatever, e.g. finishing and not do the job or misbehave with each other. So, the thing is that my program crashes when I call a function for each thread calling itself. The code can be seen below. If I change the name of the function testExclusion to testExclusion22 works fine, otherwise the program continues going without stopping. Same thing happens if I have a limited number of self-calls e.g. a 3 times loop -> see testFunction(). So my question is, what is wrong? Do I have something written wrong or this is not supported and if it is how can I do so? Thanks a lot!
// 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);
}
Upvotes: 0
Views: 1253
Reputation: 18811
Your printingFunction()
is forever calling itself, without any exit condition:
void printingFunction() {
printf("This is for testing ONLY!");
printingFunction();
}
Upvotes: 1