这个简单的pthread代码的奇怪行为
Strange behavior of this simple pthread code
如果我编译并运行下面的代码
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
但是如果我注释掉sleep(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 /**
谁能解释一下发生了什么事?为什么我得到不正确的输出与sleep(1)注释掉?这是我用来编译代码的
g++ -Wall -Wextra -O2 -ggdb -pthread 5.cpp -o 5
这是因为主线程,即创建其他线程的主线程,在所有创建的线程有时间运行之前退出(通过pthread_exit
的优势-无论如何,您将在main
结束时退出)。i
数组在被所有线程读取时被销毁并包含垃圾。
你必须等待-即pthread_join
-为你的子线程在main可以退出之前。
sleep
为线程的执行赢得了一些时间,但它仍然取决于操作系统来决定谁在什么时候运行。可能发生sleep(1)
足够,或者不够,或者没有人跑,直到邮递员来送货。
呼叫pthread_join
,你会安全的。
您没有提及您正在使用的是否是单核机器。
为什么你认为它是不正确的输出?
操作系统可以自由地以任何顺序处理线程。休眠将产生该线程,并在CPU上启用另一个线程。这就是为什么代码将产生如下所示的输出。
当你注释掉sleep(1);
时,主线程将一次创建所有线程,并且可能比系统生成这些线程更快。线程本身是并发的,因此它们的输出可以以任意顺序进行。当您使用sleep(1);
时,线程将被创建,主线程将等待一秒钟,而创建的线程将被调度,运行和输出在不到一秒钟的时间内,然后下一个线程将被创建。
created 4 threads
将在循环结束后立即写入。如果没有sleep(1);
,这个循环在任何派生线程可以运行之前立即结束,因此它将在线程的输出之前出现。在休眠状态下,除了最后一个线程之外的所有线程都经过了它们的输出,当循环离开时,Created 4 threads
将出现在最后一个尚未调度的创建线程之前。
相关文章:
- 在c++中用vector填充一个简单的动态数组
- (C++)分析树以计算返回错误值的简单算术表达式
- 我的简单if-else语句是如何无法访问的代码
- 使用简单类型列表实现的指数编译时间.为什么
- 如何在BST的这个简单递归实现中消除警告
- 一种在C++中读取TXT配置文件的简单方法
- 关于简单C++函数(is_palindrome)的逻辑的问题
- 显示错误输出的简单数组排序程序
- 当无法使用模板和宏时,生成类型变体C++代码的最简单方法是什么?
- 退出简单while循环时出现问题
- 为什么简单的算术减法在"if"条件下不起作用?
- C++-字符串是否包含一个带有简单循环的单词
- 关于 c++ 函数中指针赋值的简单问题
- 从函数返回任意简单类型的数据
- 如何在没有函数的情况下编写此代码并使C++更简单?
- 有没有办法简单地从 GPU 调用多个 cpp 输出文件?
- 在简单示例中,Python3 + ctypes 回调会导致内存泄漏
- 在简单的 pthread 中运行服务器
- 使用pthread的简单程序的输出
- 这个简单的pthread代码的奇怪行为