如何在 C++ 中使用 POCO 从多个线程打印到标准输出
How to print to standard output from multiple threads using POCO in c++
我想创建一个启动 5 个打印线程的简单程序 "hello world! This is thread [thread number]"。
每个打印操作之前都应该有一个随机等待操作,以证明线程是 运行ning 并发的。 (线程将以随机顺序打印它们的消息,而不是按顺序打印,如果线程 运行ning 按顺序打印。)
这是应该实现此目的的代码:
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 循环中,那么程序 运行s 没有错误,但它按顺序打印线程。 (因为 join()
在继续之前等待线程完成,因此线程是顺序执行的而不是并发的。
如何使线程 运行 并发并在调用 cout
后立即将消息打印到标准输出?
由于您在 for 循环中创建对象,因此它们的生命周期将在每次迭代后立即结束。这会导致问题。正如 documentation for start()
所述:
Note that the given Runnable object must remain valid during the entire lifetime of the thread, as only a reference to it is stored internally.
您需要以一种使它们在循环外也保持活动的方式创建可运行对象。
正如 Sami 所说,运行nable 在线程完成之前就被销毁了。我删除了 for 循环并明确地键入了每一行。我还删除了一个线程,因为我只能 运行 4 个线程而不会导致崩溃。最后,我为每个线程创建了一个单独的 运行nable,因为在原始代码中每个线程都使用相同的。
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;
}
我想创建一个启动 5 个打印线程的简单程序 "hello world! This is thread [thread number]"。
每个打印操作之前都应该有一个随机等待操作,以证明线程是 运行ning 并发的。 (线程将以随机顺序打印它们的消息,而不是按顺序打印,如果线程 运行ning 按顺序打印。)
这是应该实现此目的的代码:
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 循环中,那么程序 运行s 没有错误,但它按顺序打印线程。 (因为 join()
在继续之前等待线程完成,因此线程是顺序执行的而不是并发的。
如何使线程 运行 并发并在调用 cout
后立即将消息打印到标准输出?
由于您在 for 循环中创建对象,因此它们的生命周期将在每次迭代后立即结束。这会导致问题。正如 documentation for start()
所述:
Note that the given Runnable object must remain valid during the entire lifetime of the thread, as only a reference to it is stored internally.
您需要以一种使它们在循环外也保持活动的方式创建可运行对象。
正如 Sami 所说,运行nable 在线程完成之前就被销毁了。我删除了 for 循环并明确地键入了每一行。我还删除了一个线程,因为我只能 运行 4 个线程而不会导致崩溃。最后,我为每个线程创建了一个单独的 运行nable,因为在原始代码中每个线程都使用相同的。
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;
}