【问题标题】:C - Thread exit sets variable to 0C - 线程退出将变量设置为 0
【发布时间】:2021-07-06 07:08:36
【问题描述】:

以下主要,我希望发现等于 false,它是。但是,treeInfo->elem 的 main 中的最终打印不是6,而是0。我不明白这怎么可能。变量绝不会设置为 0。任何建议都将不胜感激。

int main() {
pthread_mutex_init(&myMutex, NULL);
pthread_t threads[5];
nodeinfo_t * treeInfo = malloc(sizeof(nodeinfo_t));

int myInt = 5;
int myIntTwo = 6;
int found;
treeInfo->elem = &myIntTwo;
node_t * myTree = createTree(&myInt);
treeInfo->node = myTree;

pthread_create(&threads[3],NULL,search,treeInfo);
pthread_join(threads[3],(void *) &found);

printf("THE VALUE OF ELEM IS %d", *(treeInfo->elem));
}
int search(void * args) {
    nodeinfo_t * nodeInfo = (nodeinfo_t *) args;
    node_t * node = nodeInfo->node;
    int * toFind = nodeInfo->elem;
    
    if (node == NULL) {
        pthread_mutex_unlock(&myMutex);
        return 0;
    }
    
    if (node->parent == NULL) {
        pthread_mutex_lock(&myMutex);
    }

    if (node->elem == *toFind) {
        pthread_mutex_unlock(&myMutex);
        return 1;
    } else if (node->elem< *toFind) {
        nodeInfo->node = node->right;
        return search(nodeInfo);
    } else if (node->elem > *toFind) {
        nodeInfo->node = node->left;
        return search(nodeInfo);
    }
}

编辑:可重现

typedef struct _node {
    int elem;
    struct _node * parent;
    struct _node * left;
    struct _node * right;
} node_t;

typedef struct _nodeinfo {
    node_t * node;
    int * elem;
} nodeinfo_t;

pthread_mutex_t myMutex;

node_t * createTree(int * firstElem) {
    // allocate memory in heap for size of node type
    node_t * root = malloc(sizeof(node_t));
    // set element of root to first int in tree
    root->elem = *firstElem;
    // set everything else blank
    root->left = NULL;
    root->right = NULL;
    root->parent = NULL;
    // return pointer to start of tree node
    return root;
}

【问题讨论】:

  • 请尝试创建minimal reproducible example 向我们展示。特别是createTree 函数有什么作用?
  • 与您的问题无关,但由于分配nodeInfo-&gt;node = node-&gt;right;(以及另一个),您将从“树”中松散节点并拥有内存泄漏.
  • 今天的课程:始终阅读手册页、参考资料和示例。并且始终在启用额外警告的情况下构建,您将其视为必须修复的错误。
  • 为什么你删除了问题中的所有代码,从而使答案无效?我已恢复编辑。

标签: c pointers gdb pthreads


【解决方案1】:

问题是你认为线程函数返回int 值。他们确实返回指针(更具体地说是void *)。

如果您在启用警告的情况下进行构建,您应该会收到一条警告,指出 search 函数与 pthread_create 期望的不匹配。

pthread_join 函数需要一个指针指向void ** 类型的指针

这种返回类型的不匹配会导致未定义的行为


要解决您的问题,您需要从 search 函数返回一个指针。但是,这是通常认为可以通过特殊转换将值转换为指针的情况之一。

例如:

void *search(void * args) {
    nodeinfo_t * nodeInfo = (nodeinfo_t *) args;
    node_t * node = nodeInfo->node;
    int * toFind = nodeInfo->elem;
    
    if (node == NULL) {
        pthread_mutex_unlock(&myMutex);
        return (void *) (intptr_t) 0;  // Note the double casting here
    }

    // ...
}

然后您需要使用指针来获取返回值,并进行相反的强制转换以获取值:

void *found_ptr;
pthread_join(threads[3], &found_ptr);
int found = (int) (intptr_t) found_ptr;

至于 可能 发生的事情是您在 64 位系统上,其中指针是 64 位,但 int 只有 32 位。这种大小不匹配将导致堆栈粉碎错误,其中变量myIntTwo 被线程的返回值覆盖。

【讨论】:

    猜你喜欢
    • 2017-02-03
    • 1970-01-01
    • 1970-01-01
    • 2019-06-13
    • 2016-03-25
    • 1970-01-01
    • 1970-01-01
    • 2016-08-07
    • 2021-09-26
    相关资源
    最近更新 更多