我正在学习多线程程序,我希望以下代码片段是一个无限循环的打印“foo"
而不会发生任何事情
期望:
foofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoofoo
现实:
好像线程甚至没有被创建,我做错了什么?如何创建一个将执行分配给它的任何功能的线程
源代码
#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
答案 0 :(得分:2)
线程已创建,但在它们运行之前,主线程退出,程序终止(它也是UB)。你必须等待你的主题:pthread_join
不需要while ( cont == false )
。
答案 1 :(得分:1)
没有打印,因为输出缓冲区不是刷新。
在print
函数中,例如。
std::cout << "Foo" << std::flush;
答案 2 :(得分:1)
我的哦我的...从哪里开始?
Joachim Pileborg给出了你没有看到东西的原因:线程创建得很好并完成他们的工作,但由于你的主程序永远不会退出而且没有人输出换行符,所以行缓冲输出永远不会刷新。
你的主程序在一个永远不会改变的标志上浪费CPU循环。尝试使用标志同步线程是非常糟糕的,尽管新的C ++ 11扩展使原子变量成为线程编程的alpha和omega。
您必须使用某种同步来等待线程终止。最常见的机制是pthread_join
。
将相同的参数实例传递给线程的每个实例会创建一个完美的竞争条件。您无法保证线程将按预期顺序读取参数(即在主循环更改它们以准备下一个线程启动之前)。您应该将每个线程传递给它自己的t_info
私有实例(或者在此结构上设置某种同步机制)。
即使在解决了所有这些问题之后,您也应该只需要3个“Foo”,因为每次打印后都会退出。
由于您没有序列化cout
访问(即您不使用某种同步对象(如互斥锁)保护它们),因此各种线程的输出可能会随机混合(即你可以看到类似“FoFFooooo”的东西)。
答案 3 :(得分:0)
在任何其他线程打印出任何内容之前,主线程可能会以此结束(并使其与所有其他线程相混淆)。
要解决此问题,请在结束之前使所有其他线程上的主线程连接循环(pthread_join()
为所有创建的线程ID),或者使用pthread_exit()
结束主线程。
同样传递struct threadInfo
相同实例的地址(即(void*)&t_info
)很可能不是您想要的。
答案 4 :(得分:0)
pthreads没有任何问题。如果要确保输出中的序列,则需要使用锁定和刷新来封闭打印输出行,以便强制执行,
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