pthread_create未正确执行
pthread_create does not execute properly
我正在学习多线程程序,并期望以下代码片段是打印"foo"
"的无限循环,而什么都没发生
预期:
foofoofoofoo
现实:
就好像线程还没有创建一样,我做错了什么???我如何创建一个线程来执行分配给它的任何函数
源代码
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <iostream>
void* print(void*);
struct threadInfo
{
int threadID;
int threadNo;
};
int main()
{
pthread_t thread[3];
bool cont = false;
int i = 1;
int max = 3;
while ( cont == false )
{
if ( i <= max )
{
threadInfo t_info;
t_info.threadID = i ;
t_info.threadNo = i ;
pthread_create(&thread[i-1],NULL,print,(void*)&t_info);
i++;
}
}
}
void* print(void* arg)
{
std::cout << "Foo" ;
pthread_exit(NULL);
}
以下代码是在Ubuntu命令行上使用以下命令编译的
g++ test.cpp -o test -lpthread
创建了线程,但在它们运行之前,主线程退出,程序终止(也是UB)。您必须等待线程:pthread_join
不需要while ( cont == false )
。
没有打印任何内容,因为输出缓冲区没有被刷新。
在print
功能中,执行例如
std::cout << "Foo" << std::flush;
天哪…从哪里开始?
Joachim Pileborg给出了你看不到任何东西的原因:线程创建得很好,并完成了它们的工作,但由于你的主程序永远不会退出,也没有人输出换行符,所以行缓冲输出永远不会刷新。
您的主程序在一个永远不会更改的标志上浪费CPU循环。尽管新的C++11扩展让原子变量成为线程编程的alpha和omega,但尝试用标志同步线程是非常糟糕的
您必须使用某种同步器来等待线程终止。最常见的机制是pthread_join
。
将相同的参数实例传递给线程的每个实例会创建一个完美的竞争条件。您不能保证线程会按照您想要的顺序读取参数(即在主循环更改参数以准备下一次线程启动之前)。您应该给每个线程传递它自己的t_info
私有实例(或者在这个结构上设置某种同步机制)。
即使在修复了所有这些问题之后,您也应该只期望3个"Foo",因为每个线程在一次打印后都会退出。
由于您没有序列化cout
访问(即,您没有用某种同步对象(如互斥对象)来保护它们),因此各种线程的输出可能会随机混合(即,可以看到类似"FoFFooooo"的内容)。
在任何其他线程打印出任何内容之前,主线程可能会结束(并以此来颤动所有其他线程)。
要解决此问题,请在结束前使所有其他线程上的主线程join loopig-around(创建的所有线程ID为pthread_join()
),或者使用pthread_exit()
结束主线程。
此外,传递struct threadInfo
的相同实例的地址,每个胎面(即:(void*)&t_info
)很可能不是您想要的。
pthreads没有任何问题。如果你想确保输出中的顺序,你需要用一个锁和一个flush来包围打印输出行,这样你就可以强制执行
1. A thread only finishes once the message has actually been printed out
2. Threads wait for each other so that no two threads write to the output at the same time
- 在执行其他功能的同时播放动画(LED矩阵和Arduino/ESP8266)
- C++,系统无法执行指定的程序
- 使用C++中的模板和运算符重载执行矩阵运算
- 创建一个函数以在输入为负数或零时输出字符串.第一次执行用户定义的函数
- 执行函数时导致崩溃的变量
- 无论条件是否为true,if总是在c++中执行
- 当函数模板参数是具有默认参数的类模板时,函数模板参数的推导如何执行
- 在C++中对T*类型执行std::move的意外行为
- 使用QProcess执行命令,并将结果存储在QStringList中
- 如何在没有信号的情况下从C++执行QML插槽
- 如何确认我的constexpr表达式实际上已经在编译时执行
- C++17中的并行执行策略
- QML按钮点击功能执行顺序
- 程序在执行程序的其余部分之前退出
- 为什么catch中的代码没有被执行
- C++从其他 constexpr 创建 lambda 不能按顺序执行 Constexpr
- 将执行、作业和WinAPI相乘
- Firebase C++VS2018 SDL2-在Firebase::app::create(..)上执行异常处理
- sqllite CREATE INDEX执行返回错误
- 无法在Qt中执行"SHOW CREATE TABLE"查询