如何在 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;
}