我想创建一个简单的程序,启动5个线程打印“hello world!这是线程[线程号]”。
每个打印操作之前都应进行随机等待操作,以证明线程正在并发运行。 (线程将以随机顺序打印其消息,而不是按顺序打印,如果线程按顺序运行则会发生。)
以下是应该实现此目的的代码:
Poco::Thread thread[5];
class HelloRunnable: public Poco::Runnable
{
public:
HelloRunnable(int arg)
{
n = arg;
}
int n;
virtual void run()
{
usleep(rand()%100000);
std::cout << "Hello, world! This is thread " << n << std::endl;
}
};
int main()
{
for(int i=0; i<5; i++)
{
HelloRunnable runnable(i);
thread[i].start(runnable);
}
for(int i=0; i<5; i++)
{
thread[i].join();
}
return 0;
}
但是,在运行时,这会给出错误:
//pure virtual method called
//terminate called without an active exception
//The program has unexpectedly finished.
如果相反,我将thread[i].join()
放在与thread[i].start()
相同的for循环中,然后程序运行没有错误,但它按顺序打印线程。 (Becuase join()
等待线程完成后继续前进,因此线程按顺序而不是同时执行。
如果调用cout
,如何让线程同时运行并将消息打印到标准输出?
答案 0 :(得分:1)
由于您在for循环中创建了对象,因此它们的生命周期将在每次迭代后立即结束。这会引起问题。作为start()
状态的documentation:
请注意,给定的Runnable对象必须在线程的整个生命周期内保持有效,因为只在内部存储对它的引用。
您需要以一种使它们在循环外保持活动的方式创建runnable。
答案 1 :(得分:0)
正如萨米所说,在线程完成之前,可运行的东西被摧毁了。我删除了for循环并明确键入每一行。我还删除了一个线程,因为我只能运行4个线程而不会导致崩溃。最后,我为每个线程创建了一个单独的runnable,就像在原始代码中每个线程使用相同的线程一样。
Poco::Thread thread[5];
class HelloRunnable: public Poco::Runnable
{
public:
HelloRunnable(int arg)
{
n = arg;
}
int n;
virtual void run()
{
//sleep for random length of time
timeval t;
gettimeofday(&t, NULL);
srand(t.tv_usec * t.tv_sec);
int uS = rand()%100000;
usleep(uS);
//print message
std::cout << "Hello, world! This is thread " << n << " I slept for "<< uS << "uS" <<std::endl;
return;
}
};
int main()
{
HelloRunnable runnable1(1);
thread[1].start(runnable1);
HelloRunnable runnable2(2);
thread[2].start(runnable2);
HelloRunnable runnable3(3);
thread[3].start(runnable3);
HelloRunnable runnable4(4);
thread[4].start(runnable4);
thread[1].join();
thread[2].join();
thread[3].join();
thread[4].join();
return 0;
}