0

我编写了一个小型测试程序来了解signal and slotboost 提供的机制及其在不同线程中发布时的行为。我想在不同的线程中调用插槽,但是我的程序的输出显示插槽没有在发出信号的不同线程中被调用。

#include <iostream>

#include <boost/thread.hpp>
#include <boost/chrono.hpp>
#include <boost/random.hpp>
#include <boost/signals2.hpp>
#include <boost/asio/io_service.hpp>
#include <boost/signals2/signal.hpp>


boost::signals2::signal<void (int)> randomNumberSig;


// ---------------- Thread 1 ----------------

boost::asio::io_service thread1_serv;

void handle_rnd_1(int number)
{
    std::cout << "Thread1: " << boost::this_thread::get_id() << " & Number is " << number << std::endl;
}

void thread1_init(void)
{
    std::cout << "Thread 1 Init" << std::endl;
    boost::asio::io_service::work work (thread1_serv); 
    randomNumberSig.connect([] (int num) -> void {
        std::cout << "Slot called from main thread" << std::endl;
        thread1_serv.post(boost::bind(handle_rnd_1, num));
    });
}

void thread1_loop(void)
{

}

void thread1(void)
{
    thread1_init();
    while (true) {
        thread1_serv.run();
        thread1_loop();
    }
}

int main(int argc, char *argv[])
{
    std::cout << "Starting the Program" << std::endl;
    boost::thread t1(&thread1);

    while (1) {
        int num = 2;

        std::cout << "Thread " << boost::this_thread::get_id() << " & Number: " << num << std::endl;
        randomNumberSig(num);
        boost::this_thread::sleep_for(boost::chrono::seconds(num));
    }
    return 0;
}

程序的输出是:

Starting the Program
Thread 7fae3a2ba3c0 & Number: 2
Thread 1 Init
Thread 7fae3a2ba3c0 & Number: 2
Slot called from main thread
Thread 7fae3a2ba3c0 & Number: 2
Slot called from main thread
Thread 7fae3a2ba3c0 & Number: 2
Slot called from main thread

我怀疑post()的方法io_service无法正常工作,或者我在初始化io_service.

4

1 回答 1

2

您没有run正确处理函数的调用。

你过去常常在无事可做时work阻止run结束。但是你work是本地的,thread1_init所以当这个函数结束时,当没有要调用的处理程序时work 被销毁并退出。io_service::run完成run后,io_service标记为已停止,需要在调用restart之前调用run(作为后续调用)。如果您不调用restart,则run立即返回而不处理任何处理程序 - 这就是您看不到它们的原因。

所以第一个解决方案是创建work其生命周期与io_service(仅使用全局变量 - 丑陋)相同:

boost::asio::io_service thread1_serv;
boost::asio::io_service::work work(thread1_serv);

另一种解决方案,不要使用,只需在之前work调用:restartrun

thread1_init();
while (true) {
    thread1_serv.restart();
    thread1_serv.run();
    thread1_loop();
}

魔杖盒测试

于 2019-11-17T14:50:41.820 回答