这个简单的pthread代码的奇怪行为

时间:2011-08-16 19:37:07

标签: c++ pthreads

如果我将编译并运行下面的代码

  1 #include <iostream>
  2 #include <pthread.h>
  3 #include <cstdio>
  4 #include <cstdlib>
  5
  6 #define NTHREADS 4
  7 #define N 100
  8 #define MEGEXTRA 1000000
  9
 10 using namespace std;
 11
 12 pthread_attr_t attr;
 13
 14 void *doWork (void *threadid) {
 15     double A[N][N];
 16     int tid = *(reinterpret_cast<int *>(threadid));
 17     size_t myStackSize;
 18     pthread_attr_getstacksize (&attr, &myStackSize);
 19     cout << "Thread " << tid << ": stack size = " << myStackSize << " bytes" << endl;
 20
 21     for (int i = 0; i < N; i++) {
 22         for (int j = 0; j < N; j++) {
 23             A[i][j] = ((i * j) / 3.452) + (N - 1);
 24         }
 25     }
 26
 27     pthread_exit (NULL);
 28 }
 29
 30 int main () {
 31     pthread_t threads[NTHREADS];
 32     size_t stackSize;
 33
 34     pthread_attr_init (&attr);
 35     pthread_attr_getstacksize (&attr, &stackSize);
 36
 37     cout << "Default stack size = " << static_cast<long>(stackSize) << endl;
 38
 39     stackSize = sizeof(double) * N * N + MEGEXTRA;
 40     cout << "Amount of stack needed per thread = " << static_cast<long>(stackSize) << endl;
 41
 42     pthread_attr_setstacksize (&attr, stackSize);
 43     cout << "Creating threads with stack size = " << static_cast<long>(stackSize) << endl;
 44
 45     int i[NTHREADS];
 46     for (int j = 0; j < NTHREADS; j++) {
 47         sleep(1);
 48         i[j] = j;
 49
 50         int rc = pthread_create(&threads[j], &attr, doWork, reinterpret_cast<void *>(&i[j]));
 51         if (rc) {
 52            cout << "Error Code: " << rc << endl;
 53             exit (-1);
 54         }
 55     }
 56
 57     cout << "Created " << NTHREADS << " threads" << endl;
 58     pthread_exit(NULL);
 59 }

我得到以下输出:

Default stack size = 8388608
Amount of stack needed per thread = 1080000
Creating threads with stack size = 1080000
Thread 0: stack size = 1080000 bytes
Thread 1: stack size = 1080000 bytes
Thread 2: stack size = 1080000 bytes
Created 4 threads
Thread 3: stack size = 1080000 bytes

但如果我要评论睡眠(1);在第47行,我得到以下输出

Default stack size = 8388608
Amount of stack needed per thread = 1080000
Creating threads with stack size = 1080000
Created 4 threads
Thread 3: stack size = 1080000 bytes
Thread 2: stack size = 1080000 bytes
Thread 1: stack size = 1080000 bytes
Thread 9251904: stack size = 1080000 bytes /** ERROR should be Thread 0: stack size = 1080000 /**

有谁可以解释发生了什么?为什么睡眠(1)注释掉后输出错误?

这就是我用来编译代码的原因

g++ -Wall -Wextra -O2 -ggdb -pthread 5.cpp -o 5

3 个答案:

答案 0 :(得分:5)

那是因为主线程(创建其他线程的线程)退出(通过pthread_exit的顶点 - 并且您无论如何都会在main的末尾获得)在所有创建的线程都有时间运行之前。 i数组在被所有线程读取时被破坏并包含垃圾。

你必须等待 - 即pthread_join - 你的子线程才能在main退出之前。

sleep会花一些时间让线程执行,但仍需要操作系统决定谁在什么时候运行。可能会发生sleep(1)足够,或者不够,或者没有人在邮递员来到并交付之前一直运行。

致电pthread_join,您就安全了。

答案 1 :(得分:1)

您没有提及它是否是您正在使用的单核机器。

为什么你认为输出不正确?

操作系统可以按任意顺序自由处理线程。睡眠将产生该线程并在CPU上启用另一个线程bash。这就是代码生成所示输出的原因。

答案 2 :(得分:0)

当您注释掉sleep(1);时,主线程将一次创建所有线程,并且可能比生成这些线程的系统更快。线程本身并发,因此它们的输出可以任意顺序。 当您使用sleep(1);创建线程时,主线程将等待一秒钟,而创建的线程将在不到一秒的时间内被调度,运行和输出,然后将创建下一个线程。 / p>

循环结束后,created 4 threads将被写入。没有sleep(1);这个循环在任何生成的线程可以运行之前立即完成,所以它将在线程的输出之前。在休眠状态下,除了last之外的所有线程都超过了它们的输出,当循环离开时,Created 4 threads将在最后一个尚未安排的线程之前到来。