Как лучше всего обрабатывать синхронизированные обратные вызовы, которые влияют на объект, совместно используемый разными потоками? - PullRequest
0 голосов
/ 17 июня 2020

У меня есть класс, назовем его Foo foo, который содержит данные, полезные для нескольких потоков. Эти потоки могут вызывать операции чтения и записи (например, foo-> emplace (something)), которые я защищал мьютексом внутри Foo и добавил блокировки мьютексов к операциям. Вот где я не уверен, когда дело доходит до реализации. Мне нужно добавить еще одну часть общей информации в foo, где я должен вызвать foo-> emplace2 (somethingElse), и это сохранит somethingElse в std :: set, но это должно храниться только в течение минуты.

Как к этому подходить? Могу ли я создать новый поток изнутри foo всякий раз, когда вызывается emplace2, и внутри этого потока emplace, засыпаю на 60 секунд, а затем стираю? Мне кажется, что есть способ лучше, чем создавать множество потоков каждый раз, когда вызывается emplace2.

Код не нужен, просто общие рекомендации по реализации.

1 Ответ

1 голос
/ 17 июня 2020

У вас есть несколько вариантов:

Один поток на запрос

иначе ваше решение

Преимущества:

  • легко реализовать
  • точное время удаления

Недостатки:

  • создано много потоков. Но опять же, все потоки спят всю свою жизнь, поэтому, возможно, это не проблема, которую стоит решать.

Одна очередь и один поток, который периодически проверяет просроченные запросы

Создайте очередь, которая хранит все запросы вместе со сроком их действия. Имейте один поток, который периодически просыпается и удаляет все просроченные потоки

Преимущества:

  • easy-i sh для реализации
  • только один поток

Недостатки:

  • Необходимо пойти на компромисс:
    • увеличить частоту пробуждения и проверки: это увеличивает время точности удаления запросов, но также увеличивает количество бесполезных пробуждений
    • снизить частоту пробуждения и проверки: это снижает точное время удаления запросов, но уменьшает количество бесполезных пробуждений

Один поток с точным пробуждением

Создайте одну очередь со всеми запросами с указанием времени их истечения. Имейте один поток, который просыпается только по истечении следующего запроса.

Когда добавляется запрос: сигнализируйте и пробуждайте поток, повторно вычисляйте следующий срок действия и переходите в режим ожидания до этого времени.

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

Преимущества:

  • Лучшая производительность
  • точное время удаления

Недостаток:

  • сложно-i sh реализовать

Как лучше всего ...

Как всегда, ответ: «Это зависит». Я дал вам несколько вариантов вместе с кратким анализом каждого из них. Вам решать, что реализовать, и это решение представляет собой баланс между требованиями к производительности и затратами на внедрение и обслуживание.

...