我最近开始研究 pthreads 并遇到了一个问题。所以,我有一个二叉树拓扑结构,15 个节点(0->14 个节点 ID),我为节点 3、4、5 和 6 创建了 4 个 pthread(不想为 eg 创建更多)。因此,创建的每个线程都试图到达其父节点以锁定该节点并增加其中的全局变量的值。为此,我为节点结构中的每个节点创建了一个互斥锁,并使用了 pthread_mutex_trylock 条件——否则我让他们做任何事情,例如完成而不做工作或彼此行为不端。所以,当我为每个调用自身的线程调用一个函数时,我的程序崩溃了。代码如下所示。如果我将函数 testExclusion 的名称更改为 testExclusion22 工作正常,否则程序将继续运行而不会停止。如果我的自调用次数有限,例如 3 次循环 -> 参见 testFunction(),也会发生同样的事情。所以我的问题是,有什么问题?我是否有写错的地方或不支持,如果是这样,我该怎么做?非常感谢!
// 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);
}