考虑下一段代码-

#include <iostream>

using namespace std;

int sharedIndex = 10;
pthread_mutex_t mutex;

void* foo(void* arg)
{
    while(sharedIndex >= 0)
    {
        pthread_mutex_lock(&mutex);

        cout << sharedIndex << endl;
        sharedIndex--;

        pthread_mutex_unlock(&mutex);
    }

    return NULL;
}

int main() {

    pthread_t p1;
    pthread_t p2;
    pthread_t p3;

    pthread_create(&p1, NULL, foo, NULL);
    pthread_create(&p2, NULL, foo, NULL);
    pthread_create(&p3, NULL, foo, NULL);

    pthread_join(p1, NULL);
    pthread_join(p2, NULL);
    pthread_join(p3, NULL);

    return 0;
}


我简单地创建了三个pthreads并赋予它们所有相同的功能foo,希望每个线程依次输出并减小sharedIndex

但这是输出-

10
9
8
7
6
5
4
3
2
1
0
-1
-2



我不明白为什么sharedIndex时进程没有停止
达到0。
sharedIndexmutex保护。它变成0后如何访问?线程不应该直接跳到return NULL;吗?


编辑

此外,似乎只有第一个线程会减小sharedIndex
为什么不是每个线程都递减共享资源?
这是修复后的输出-

Current thread: 140594495477504
10
Current thread: 140594495477504
9
Current thread: 140594495477504
8
Current thread: 140594495477504
7
Current thread: 140594495477504
6
Current thread: 140594495477504
5
Current thread: 140594495477504
4
Current thread: 140594495477504
3
Current thread: 140594495477504
2
Current thread: 140594495477504
1
Current thread: 140594495477504
0
Current thread: 140594495477504
Current thread: 140594478692096
Current thread: 140594487084800


我希望所有线程都会减少共享源-意思是,每个contex开关,一个不同的线程都将访问该资源并执行其操作。

最佳答案

该程序的行为是不确定的。

您尚未初始化互斥锁。您需要调用pthread_mutex_init或将其静态初始化:

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;


您在关键部分之外阅读了此变量:

while(sharedIndex >= 0)


这意味着您可以在另一个线程对其进行更新时读取垃圾值。在锁定互斥锁并对其具有独占访问权限之前,您不应阅读共享变量。

编辑:


  似乎只有第一个线程递减sharedIndex


那是因为行为不确定。解决以上问题,您应该看到其他线程正在运行。

使用您当前的代码,编译器可以假定sharedIndex从未被其他线程更新,因此它不必费心重新读取它,而只是让第一个线程运行十次,然后让其他两个线程运行一次每。


  这意味着,每个contex开关,一个不同的线程都将访问该资源并执行其操作。


无法保证pthread互斥体的行为公平。如果要保证每个线程依次运行的循环行为,则需要自己强加例如通过使用另一个共享变量(可能是条件变量)来说明要运行哪个线程,并阻塞其他线程,直到该线程轮到他们为止。

09-26 18:06