如何使用c ++中的POCO从多个线程打印到标准输出

时间:2017-07-27 12:26:32

标签: c++ multithreading cout poco-libraries

我想创建一个简单的程序,启动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,如何让线程同时运行并将消息打印到标准输出?

2 个答案:

答案 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;
}