帮助基本的线程概念/竞争条件

时间:2009-01-06 12:04:44

标签: c multithreading posix

我现在正在学习POSIX线程,但我想这只是关于多线程的一般问题,所以我希望任何人都可以帮助我。我从我正在研究的书中得到了这个例子,它证明了竞争条件:

void *thread_main(void *thread_number) {
    printf("In thread number %d.\n", *(int *)thread_number);
}

void main() {
    int i = 0;
    pthread_t thread;

    for( i = 0; i < 10; i++ ) {
        printf("Creating thread %d.\n");
        pthread_create(&thread, 0, thread_main, &i);
        printf("Created thread %d.\n");
    }
}

有一些我不明白的事情。首先,“在第5号线中”。多次打印,即使它不应该在第5号线中。在本书中,该示例显示了多次打印线程8。我也不理解*(int *)thread_number部分。我尝试将其更改为thread_number,但这只是一次又一次地给了我奇怪的数字。

这本书并没有真正解释这一点。有人能给我一个清楚的解释,这里发生了什么?我不明白为什么它不打印像:

> Creating thread 1.
> In thread number 1.
> Created thread 1.
> Creating thread 2.
> In thread number 2.
> Created thread 2.

我知道因为它是多线程的“在线号x”。部分将在不同的时间出现,但我真的不明白为什么没有正好10个“在线号x”,我创建的每个线程都有一行!

〜DESI

3 个答案:

答案 0 :(得分:3)

在创建的10个线程中的任何一个线程都有机会运行之前,for循环可能会迭代10次。在这种情况下,每个线程的*thread_number值为10(因为它是指向具有单个值的单个内存位置的指针)。

如果您没有将指针i传递给pthread_create,那么int的值最终将被视为地址,因此当您在{{{{}}中取消引用它时1}},你正在访问一些任意的内存位置,其内容可能是未定义的。你很幸运,在那种情况下你不会发生分裂。

如果您希望在每个帖子中看到thread_main的正确值,您需要在调用*thread_number之前mallocint并为其指定当前值pthread_create,如此:

i

当然,当线程完成后,你需要for( i = 0; i < 10; i++ ) { int *thread_count = malloc(sizeof(int)); *thread_count = i; printf("Creating thread %d.\n", i); pthread_create(&thread, 0, thread_main, thread_count); printf("Created thread %d.\n", i); } 内存,如下所示:

free

答案 1 :(得分:3)

首先关闭*(int *)thread_number是指针的东西 - 当你只有thread_number时,'奇怪的数字'是 main 函数中指向'i'的指针(除非我错误的是,它们应该是一次运行程序的相同数字(所以10个线程中的每一个都应该具有相同的“在线程号[数字]”))。

你需要明白这些是重复5的指针才有意义 - 每个线程都使用 main 函数中的相同底层i - 它没有被复制用于每个新线程,所以当i在 main 函数中递增时,这反映在 thread_main 函数中的thread_number中。

最后一个难题是每个新线程的设置时间然后上下文切换(更改哪个线程实际运行)不是立即的,所以在你的情况下,for循环在新创建的线程之前运行5次实际上是运行的(在本书的情况下,for循环在上下文切换之前运行8次),然后每个线程查看相同的底层i值,现在为5。

答案 2 :(得分:1)

首先,竞争条件是一件坏事。该程序按预期工作。竞争条件意味着该程序旨在破坏。

在这种情况下,您的所有线程看起来都是共享变量i。您正在向他们传递对单个共享变量的引用,当他们碰巧安排时,他们会尝试报告这些变量。

相关问题