【问题标题】:variable in thread callstack changing unexpectedly c线程调用堆栈中的变量意外更改c
【发布时间】:2020-03-24 12:14:19
【问题描述】:

使用 c11 线程,我试图确保 foo 是线程安全的。虽然foo 不可重入,但我正在尝试使用互斥锁来缓解这种情况。

我不明白为什么thrdn 的值在关键循环中会发生变化。我的理解是,对foo 的每个线程调用都会有自己的thrdn 版本,但它似乎在运行时被其他线程修改。

我尝试将thrdn 的声明上方的mtx_lock 移动并将thrdn 更改为atomic_int * 类型,但是这两者都会导致相同的行为。

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

#define THREAD_MAX 5

thrd_t threads[THREAD_MAX];
mtx_t mtx;

void foo(void * data)
{
        int* thrdn = (int *)data;

        mtx_lock(&mtx);
        for(int i = 0; i < 3; ++i) {
                printf("thread %d, number %d\n", *thrdn, i);
        }
        mtx_unlock(&mtx);
}

int main()
{
        mtx_init(&mtx, mtx_plain | mtx_recursive);
        for(int i = 0; i < THREAD_MAX; ++i){
                thrd_create(&threads[i], foo, &i);
        }

        for(int i = 0; i < THREAD_MAX; ++i){
                thrd_join(threads[i], NULL);
        }
        mtx_destroy(&mtx);
}

【问题讨论】:

  • &amp;i 是单个 i 变量的地址,它的生命周期相当有限。
  • 奇怪的是,几乎相同的场景在几个小时内被问了两次……想知道你们两个是在同一个班级还是什么?虽然那个使用 pthreads,而不是 C11 线程所以可能不是......
  • foo()的每次执行确实都有自己的thrdn,它们都指向相同局部变量i主线程执行main()。至少在该变量的生命周期结束之前。
  • 我想你可能有一点@Groo,我认为在循环中使用 &i 是安全的,但如果它在线程完成之前结束,这可能是问题。跨度>

标签: c multithreading mutex


【解决方案1】:

正如 cmets 中所述,问题在于对局部变量 i 的引用。如this 回答中所见,单独跟踪线程 ID 解决了该问题。

【讨论】:

    猜你喜欢
    • 2021-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-13
    • 1970-01-01
    • 2010-11-21
    • 2013-07-23
    • 2011-10-11
    相关资源
    最近更新 更多