Я использую библиотеку sigslot для запуска сигналов в функции. Эта функция работает в потоке с использованием QtConcurrent :: run, а сигналы связаны в основном потоке. Он работает нормально, за исключением того, что соединение сигнала не работает каждый раз (скажем, около 25% отказа).Сигналы sigslot по потокам
Это неустойчивое поведение является проблематичным, и я не могу найти решение. Сигналы в библиотеке sigslot имеют разные параметры в зависимости от контекста многопоточности, но ни одна из них не устраняет проблему.
Прежде чем пытаться повысить, я действительно хотел бы найти решение для сохранения sigslot, так как это довольно простая библиотека, и мне нужно только базовое использование сигналов и слотов в этой части кода. И я не хочу использовать Qt для этого, потому что я предпочитаю оставить эту же часть кода без Qt.
Любой намек был бы очень признателен.
Обновление: По какой-то причине, используя отчаянную попытку sigslot :: single_threaded, похоже, дает лучшие результаты.
signal1<int, single_threaded> Sig1;
Я не говорю, что это решение проблемы, поскольку для меня это не имеет смысла. Как поясняется в документации: Single Threaded В однопоточном режиме библиотека не пытается защитить свои внутренние структуры данных по потокам. Поэтому важно, чтобы все вызовы конструкторам, деструкторам и сигналам должны существовать в пределах одного потока.
Update 2:
Вот MWE. Но результаты довольно случайны. Иногда он полностью работает, иногда не все. Я знаю, это звучит странно, но в этом проблема. Я также попробовал boost :: signals2 вместо sigslot, но результат совершенно такой же. Там в исполняемый плохой доступ в буст :: signals2 :: мьютекс :: замок()
class A {
public :
A() {}
~A() {}
sigslot::signal1<int, sigslot::multi_threaded_local> sigslot_signal;
boost::signals2::signal<void (int)> boost_signal;
void func_sigslot() {
for (int i=0;i<4;i++) {
sigslot_signal.emit_signal(i);
}
}
void func_boost() {
for (int i=0;i<4;i++) {
boost_signal(i);
}
}
};
class B : public sigslot::has_slots<sigslot::multi_threaded_local> {
public :
B() {}
~B() {}
void test(int i) {
std::cout << "signal triggered, i=" << i << std::endl;
}
};
void main() {
A a;
B b;
a.sigslot_signal.connect_slot(&b, &B::test);
a.boost_signal.connect(boost::bind(&B::test, &b, _1));
QtConcurrent::run(&a, &A::func_sigslot);//->crashes when signal emitted
QtConcurrent::run(&a, &A::func_boost);//->crashes when signal emitted
boost::thread t1(boost::bind(&A::func, &a));
t1.join();//works fine
}
жаль, что не сделал MWE, я действительно искал глобальный ответ вместо отладки кода (например, «Qt и sigslot не будут работать вместе»). Поскольку поведение неустойчиво и контекст довольно запутанный, я думал, что не стоит делать пример – brahmin
Самая важная недостающая часть: нет библиотеки «sigslot». Это заброшенный проект, доступный в несколько этапов разложения из разных источников. Добавьте ссылку на версию, которую вы используете. –
Ну, я не знал об этой библиотеке. Я начал использовать, потому что нашел только хорошие отзывы. Я использую эту версию: https://sourceforge.net/p/sigslot/patches/3/ – brahmin