У меня есть несколько потоков, которые работают с несколькими элементами данных.Потоки должны выводить результаты в том же порядке, в котором я передаю данные потокам.То есть:
Thread #1: give data - start processing
Thread #2: give data - start processing
Thread #3: give data - start processing
...
Thread #n: give data - start processing
Результаты должны быть получены в том же порядке, в котором данные были переданы потокам, независимо от того, какой поток завершил обработку первым.А именно:
Thread #1: put data
Thread #2: put data
...
Чтобы различать потоки и управлять ими, я дал каждому из них идентификатор (0,1,2,...,n)
.Я использую идентификаторы для назначения данных каждому потоку, чтобы он мог их обработать.
for(int i=0; i<thread_count; i++)
give_data(i); // i is id and the function knows where to get data from
Я хочу, чтобы потоки использовали общий токен, который определяет, какой поток должен получить результат.Все тела потоков идентичны, тело выглядит так:
while(true){
auto data = get_data();
result = process_data(data);
while(token != this_id) spin;
put_data(result); // this is a synchronized call
update_token(token);
}
Моя проблема связана с token
.Сначала я попробовал нормальную ссылку (int & token
), и она, очевидно, не может работать (и я этого не ожидал).Во всяком случае, я использовал статическую переменную, и потоки не всегда получают самую последнюю.Я был удивлен, увидев, что одна нить доминирует во всем.Всякий раз, когда поток обновляет токен, он теряет свой ход, позволяя другому потоку выставить свой результат и так далее.Однако у меня доминировал один поток, как если бы токен всегда устанавливался на свой собственный идентификатор и не обновлялся.
Если бы мне пришлось угадывать, я бы сказал, что это проблема с кэшированием.Однако я не уверен.
В любом случае, я думаю об использовании std::atomic<int>
в качестве своего токена.Будет ли это работать?Если нет, что еще я должен рассмотреть делать?Что может быть лучше для синхронизации этих потоков?
Дополнительно: это похоже на плохой дизайн, и я не уверен, как это сделать лучше.Любые предложения будут очень признательны.