Я новичок в C++ (в Windows) и потоковом, и в настоящее время я пытаюсь найти решение своей проблемы с помощью мьютексов, семафоров и событий. Я пытаюсь создать класс Барьера с конструктором и методом Enter. Класс Barrier с его единственным методом Enter должен удерживать любой поток, который входит в него, до тех пор, пока ряд потоков не достигнет этого метода. Количество потоков, ожидающих его получения в контрукторе. Моя проблема заключается в том, как использовать блокировки для создания этого эффекта? мне нужно что-то вроде обратного семафора, который содержит потоки до тех пор, пока счет не будет достигнут, а не как обычные семафоры, которые позволяют потокам до тех пор, пока счет не будет достигнут. Любые идеи относительно того, как это сделать, были бы замечательными. Спасибо, Netanel.C++ Холдинг нескольких потоков
ответ
ПСЕВДОКОД план может выглядеть следующим образом:
void Enter()
{
Increment counter (atomically or with mutex)
if(counter >= desired_count)
{
condition_met = true; (protected if bool writes aren't atomic on your architecture)
cond_broadcast(blocking_cond_var);
}
else
{
Do a normal cond_wait loop-plus-predicate-check (waiting for the broadcast and checking condition_met each iteration to protect for spurious wakeups).
}
}
Может быть:
В CTOR, хранить счетчик предела и создать пустой семафор.
Когда поток вызывает Enter, сначала заблокируйте мьютексы, чтобы вы могли безопасно перемещаться внутри. Включить подсчет потока к счету лимитов. Если предел еще не достигнут, отпустите мьютекс и подождите на семафоре. Если предел достигнут, сообщите о семафоре [limit-1] раз в цикле, обнулите счетчик потоков (готов к следующему разу), отпустите мьютекс и вернитесь из Enter(). Любые потоки, которые ожидали семафора и теперь готовы/работают, должны просто вернуться из своего вызова «Ввод».
Мьютекс предотвращает пропущенную нить, которая вращается вокруг от «входа снова» до тех пор, пока все потоки, которые вызвали «Ввод» и не подождали, были установлены, и барьер сбрасывается.
Я думал о чем-то подобном. Моя проблема заключалась в том, что происходит между выпуском мьютекса и ожиданием семафора.В то время что-то может произойти, как необходимое количество потоков, идущих и освобождающих барьер, заставляя эту нить ждать следующей группы, даже если она прибыла первой ... –
Я не уверен, что вы можете достичь того, чего хотите, Войти(). Если бы каждый поток вызывал функцию Leave(), когда они покидали защищенную область (или собирались все вокруг), вы могли бы построить двухступенчатый барьер, который работал бы так, как вы этого хотите. –
Вы можете реализовать его с переменной условия.
Вот пример:
Я объявляю 25 потоков и запускать их делает функцию WorkerThread.
Условие, которое я проверяю, чтобы заблокировать/развязать потоки, равно количеству строк в секции меньше 2. (Я добавил несколько утверждений, чтобы доказать, что делает мой coode).
Мой код просто спит в критической секции и после уменьшения количества потоков в критическом разделе.
Я также добавил мьютекс для сообщений cout, чтобы иметь чистые сообщения. #include #include #include #include #include #include #include/* * утверждает/ использование патезраса;
std::mutex m;
atomic<int> NumThreadsInCritialSection=0;
int MaxNumberThreadsInSection=2;
std::condition_variable cv;
mutex coutMutex;
int WorkerThread()
{
// Wait until main() sends data
{
std::unique_lock<std::mutex> lk(m);
cv.wait(lk, []{return NumThreadsInCritialSection<MaxNumberThreadsInSection;});
}
assert (NumThreadsInCritialSection<MaxNumberThreadsInSection);
assert (NumThreadsInCritialSection>=0);
NumThreadsInCritialSection++;
{
std::unique_lock<std::mutex> lk(coutMutex);
cout<<"NumThreadsInCritialSection= "<<NumThreadsInCritialSection<<endl;
}
std::this_thread::sleep_for(std::chrono::seconds(5));
NumThreadsInCritialSection--;
{
std::unique_lock<std::mutex> lk(coutMutex);
cout<<"NumThreadsInCritialSection= "<<NumThreadsInCritialSection<<endl;
}
cv.notify_one();
return 0;
}
int main()
{
vector<thread> vWorkers;
for (int i=0;i<25;++i)
{
vWorkers.push_back(thread(WorkerThread));
}
for (auto j=vWorkers.begin(); j!=vWorkers.end(); ++j)
{
j->join();
}
return 0;
}
Надеюсь, что это поможет, скажите, если у вас есть какие-либо вопросы, я могу прокомментировать или изменить свой код.
- 1. Создание нескольких потоков C++
- 2. Холдинг построил статические массивы в памяти для нескольких файлов C++
- 3. Создание нескольких потоков в C
- 4. C - Ожидание завершения нескольких потоков
- 5. C# Ожидание завершения нескольких потоков
- 6. C - чтение нескольких файловых потоков
- 7. timer_create для нескольких потоков в C++
- 8. C Программирование нескольких потоков с использованием pthread.h
- 9. Программа C заканчивается после создания нескольких потоков
- 10. C# получить максимальное значение из нескольких потоков
- 11. Linux, C: Накопление данных из нескольких потоков
- 12. C# Использование потоков для ожидания нескольких условий
- 13. аргумент pthread_create в c программировании нескольких потоков
- 14. C# - Создание нескольких потоков с использованием Lambda
- 15. Oracle Pro * C доступ из нескольких потоков
- 16. SDL и C++: Ожидание завершения нескольких потоков
- 17. создания нескольких потоков в выпуске C
- 18. доступ к меню из нескольких потоков C#
- 19. C - синхронизация нескольких потоков с mutexs
- 20. Переключатель C# от одного до нескольких потоков
- 21. C# Обновление TextBox из нескольких потоков
- 22. Холдинг Кнопка обновления
- 23. Холдинг Временно вниз
- 24. Холдинг количество строк
- 25. Холдинг userid в ASP.net
- 26. Синхронизация нескольких потоков
- 27. создание нескольких потоков функции
- 28. Выполнение нескольких потоков
- 29. Синхронизация нескольких потоков Cuda
- 30. Считывание нескольких файлов с использованием нескольких потоков в C
Что вы сделали? – deepmax
Вы хотите использовать потоки C++ 11 или WinAPI? –
@dan - Я использую WinAPI –