2009-10-19 4 views
4

Я прошел через подобные вопросы на Stackoverflow, но до сих пор не может получить хороший ответ:сигнал и слот против многопоточности в библиотеке Boost,

  1. how boost implements signals and slots
  2. How signal and slots are implemented

Я довольно озадачен тем, как достигается этот сигнал/слот.

Q1: Из следующего кода сиг подключен к двум функциям (Hello() и World()), и кажется, что функции вызываются сериализованным образом, что также подразумевает, что одна функция (Hello ()) необходимо завершить до перехода в другую функцию (World())? => Программа с одной нитью

Q2: В любом случае, чтобы включить многопоточный сигнал/слот? (=> World() начнется мгновенно, не нужно ждать завершения Hello().) Или, если это не рекомендуется, не могли бы вы рассказать мне, почему?

Sample codes on Boost website:

struct Hello 
{ 
    void operator()() const { std::cout << "Hello";} 
}; 
struct World 
{ 
    void operator()() const { std::cout << ", World!" << std::endl;} 
}; 

boost::signal<void()> sig; 
sig.connect(Hello()); 
sig.connect(World()); 
sig(); 

Выход: Hello, World!

ответ

3

Q1:
Звонки сериализуются. Какие сигналы делают внутри, значительно упрощается:

foreach connection: 
    call handler 

Поэтому вы не хотите долго блокировать в обработчиках. Если вам нужно много работать, вы можете вызывать его оттуда, например, создав для него поток.

Q2:
сигналы будильника 1 даже не являются потокобезопасными; сигналы 2 есть, но все же выполняют сериализованные вызовы. Поскольку сигналы в основном используются для обработки событий, общий стиль не на самом деле делает большую работу в обработчиках.
Таким образом, нет никакой реальной выгоды при вызове их «параллельно», преимущества в общем не оправдывают накладные расходы на необходимые вызовы потоков.

2

Q1: Вы правы. Исправлено: my answer - the question Вы ссылаетесь на это.

Q2: Кажется, вы смущены тем, что должно быть пронизано резьбой. В процессе испускания/захвата содержит код - это слот. Поэтому, если вы хотите запустить код одновременно, вы должны разместить слоты в различных направлениях.

Такое поведение поддерживается Qt (на самом деле не знаю о повышении), а в руководстве qt есть a chapter, в котором объясняется, что для такого поведения вам, скорее всего, нужна «очередь обработки». Но тогда вам нужно будет иметь понятие «цикл событий» в потоке, который выполняет код слота (потому что вы не можете просто сказать рабочий поток «эй, перестаньте делать что-нибудь, сделайте это вместо этого!»).

Если вы не хотите ждать, вам придется немедленно создавать потоки в слотах. И вы не должны забывать использовать какую-то функцию «ожидания» в коде, к которому имеют доступ оба слота. Кстати, и boost, и Qt имеют приятные обертки вокруг системных библиотек потоков, чтобы сделать это легко.