инициализация — Использование критических разделов / семафоров в переполнении стека

Я недавно начал использовать C ++ вместо Delphi.
И есть некоторые вещи, которые кажутся совершенно другими.
Например, я не знаю, как инициализировать переменные, такие как семафоры и CriticalSections.
К настоящему времени я знаю только 2 возможных пути:
1. Инициализировать критический раздел в конструкторе глупо, поскольку каждый экземпляр будет использовать свой собственный критический раздел без какой-либо синхронизации, верно?
2. Использование глобального var и его инициализация при создании формы также не являются идеальным решением.
Может кто-нибудь сказать мне, как этого добиться?

Просто краткое объяснение того, что мне нужно Критический раздел:
Я хотел бы заполнить ListBox из разных тем.
Семафор:
Различные потоки двигают мышь, это не должно прерываться.

Спасибо!

0

Решение

В отличие от Delphi, C ++ не имеет понятия инициализации / завершения модуля (но вы уже узнали об этом).

То, что у нас осталось, очень мало. Вам нужно различать две вещи:

  • где вы объявляете свою переменную (глобальная, статический член класса, член класса, локальный для функции, статический в функции — я думаю, это охватывает все)
  • где вы инициализируете свою переменную (так как вы имеете дело с C API, вы должны вызвать функцию инициализации самостоятельно)

Дело в том, что в вашем случае это не имеет значения, где вы объявлять ваша переменная до тех пор, пока она доступна всем остальным частям вашей программы, которые в ней нуждаются, и единственное требование относительно того, где вы должны ее инициализировать, это: до того, как вы фактически начнете ее использовать (что подразумевает, прежде чем вы запустите другие потоки).

В вашем случае я бы, вероятно, использовал синглтон. Но C ++, будучи тем, чем он является, синглтоны страдают от состояния гонки во время их инициализации, и не существует чистого способа обойти это. Таким образом, в дополнение к вашему синглтону, вы должны убедиться, что он создан правильно прежде чем начать использовать его в многопоточном контексте. Простой вызов getInstance() в начале вашего main() сделает трюк (или в любом другом месте, которое вы считаете нужным). Как видите, это заботится только о том, где вы объявлять ваша переменная, а не где вы инициализировать это, но, к сожалению, C ++ имеет важные ограничения, когда дело доходит до многопоточности (это недостаточно указано), так что нет никакого пути к этому.

Подводя итог: просто делайте что хотите (пока это работает) и перестаньте беспокоиться.

1

Другие решения

На мой взгляд, вам нужен только критический раздел, чтобы синхронизировать обновления со списком из разных потоков. Мышь будет продолжать двигаться. Семафор не подходит для решения. Вы инициализируете критическую секцию в своем конструкторе классов. где список находится. Напишите метод обновления списка.

//psudo code
UpdateListBox()
{
//enter critical section
//update
//leave critical section
}

Все потоки будут вызывать этот метод для обновления списка.

информация о критическом разделе здесь
http://msdn.microsoft.com/en-us/library/windows/desktop/ms683472%28v=vs.85%29.aspx

0