Синхронизация. Что-то я туплю...

Тема в разделе "WASM.WIN32", создана пользователем _Juicy, 10 авг 2011.

  1. _Juicy

    _Juicy Active Member

    Публикаций:
    0
    Регистрация:
    12 авг 2003
    Сообщения:
    1.159
    Адрес:
    SPb
    Основной поток создает несколько дополнительных. Дополнительные потоки выполняют некоторую работу и благополучно завершаются.
    Как основной поток может определить перед закрытием, что все дополнительные отработали? WaitForMultipleObjects(handles) не хотелось бы, т.к. неизвестно, сколько будет дополнительных потоков.
     
  2. Honorary_BoT

    Honorary_BoT New Member

    Публикаций:
    0
    Регистрация:
    21 мар 2008
    Сообщения:
    87
    А в чем проблема с тем, что неизвестно заранее кол-во потоков? Храните в переменной их количество и хэндлы.
     
  3. _Juicy

    _Juicy Active Member

    Публикаций:
    0
    Регистрация:
    12 авг 2003
    Сообщения:
    1.159
    Адрес:
    SPb
    Заранее неизвестен размер массива под хендлы. Он может оказаться чересчур большим.
     
  4. Honorary_BoT

    Honorary_BoT New Member

    Публикаций:
    0
    Регистрация:
    21 мар 2008
    Сообщения:
    87
    ОМГ, это как-то странно. Хэндл имеет размер 4 или 8 байт. Если сделать массив динамическим на памяти из кучи, через HeapAlloc / HeapRealloc, то туда можно такое количество хэндлов засунуть, сколько потоков вы точно не создадите...
     
  5. _Juicy

    _Juicy Active Member

    Публикаций:
    0
    Регистрация:
    12 авг 2003
    Сообщения:
    1.159
    Адрес:
    SPb
    Вот только реализации динамического массива из кучи мне не хватало :'(
    Тогда уж проще счетчик с критической секцией...
     
  6. shchetinin

    shchetinin Member

    Публикаций:
    0
    Регистрация:
    27 май 2011
    Сообщения:
    715
    WaitForMultipleObjects максимальное количество хендлов для ожидания MAXIMUM_WAIT_OBJECTS = 64.

    Squash
    Счетчик потоков? ну всмысле семафор ...
     
  7. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    Squash

    Судя по всему C++ - не ваша тема :) Сделайте статический массив заранее определенного размера, скажем на 64 килобайта. Больше потоков все равно нет смысла делать, комп захлебнется на переключении задач. А WaitForMultipleObjects не нужен - достаточно цикла из WaitForSingleObjects.

    PS. Еслечо:

    Код (Text):
    1. boost::thread_group threads.
    2.  
    3. threads.create_thread(...);
    4. threads.create_thread(...);
    5. threads.create_thread(...);
    6. ...
    7. threads.join_all();
     
  8. Honorary_BoT

    Honorary_BoT New Member

    Публикаций:
    0
    Регистрация:
    21 мар 2008
    Сообщения:
    87
    Ну ага, и цикл будет жрать процессорное время, когда часть потоков завершится, а часть ещё будет работать. Изначально тоже подумал о семафоре, забыл, что максимум 64 объекта можно ждать. Так что +1 shchetinin.

    Хотя, да, не сильно будет жрать, изредка подъедать =)
     
  9. _DEN_

    _DEN_ DEN

    Публикаций:
    0
    Регистрация:
    8 окт 2003
    Сообщения:
    5.383
    Адрес:
    Йобастан
    Honorary_BoT

    Лолшто? WaitForSingleObject с INFINITE же.
     
  10. 7mm

    7mm New Member

    Публикаций:
    0
    Регистрация:
    15 дек 2009
    Сообщения:
    442
    AtomicCounter вам в помощь. Семафор, то бишь :) Дополнительный поток стартует - INC, завершается - DEC. В основном потоке -- while (AtomicCounter) { Sleep(1); }
     
  11. _Juicy

    _Juicy Active Member

    Публикаций:
    0
    Регистрация:
    12 авг 2003
    Сообщения:
    1.159
    Адрес:
    SPb
    Мне семафор первым делом в голову пришел. Только что-то я никак не могу врубиться, как его использовать. Ворд Аутомейшн вчера взорвал мне мосх :dntknw:
     
  12. _Juicy

    _Juicy Active Member

    Публикаций:
    0
    Регистрация:
    12 авг 2003
    Сообщения:
    1.159
    Адрес:
    SPb
    Shit.
    InterlockedXXX - вот что спасет отца русской демократии.
    Всем спасибо.
     
  13. ip_man

    ip_man New Member

    Публикаций:
    0
    Регистрация:
    7 июн 2011
    Сообщения:
    43
    ActiveThreads
     
  14. 7mm

    7mm New Member

    Публикаций:
    0
    Регистрация:
    15 дек 2009
    Сообщения:
    442
    А ви таки не знали про Interlocked???
     
  15. _Juicy

    _Juicy Active Member

    Публикаций:
    0
    Регистрация:
    12 авг 2003
    Сообщения:
    1.159
    Адрес:
    SPb
    Написано же - туплю.
    И потом, у него есть недостатки. В общем случае, основному потоку придется выполнять бесконечный цикл, периодически проверяя переменную.
     
  16. shchetinin

    shchetinin Member

    Публикаций:
    0
    Регистрация:
    27 май 2011
    Сообщения:
    715
    Squash
    Уже сказали узайте семафор ... и не надо не какого гавно кодеса придумывать ...
     
  17. _Juicy

    _Juicy Active Member

    Публикаций:
    0
    Регистрация:
    12 авг 2003
    Сообщения:
    1.159
    Адрес:
    SPb
    Уважаемый shchetinin, не могли бы вы немного подробнее объяснить, как можно использовать семафор в данном конкретном случае?
     
  18. shchetinin

    shchetinin Member

    Публикаций:
    0
    Регистрация:
    27 май 2011
    Сообщения:
    715
    Squash
    Почитайте про семафоры , там есть ReleaseSemaphore котый вернет счетчик , и это будет InerProc .

    Короче специально для ВАС псевдо убидый код построеный на EVENT (Для так будет проще)

    Код (Text):
    1. HANDLE g_SyncEvent   = CreateEventW(NULL, TRUE, TRUE, NULL);
    2. DWORD  g_SyncCounter = 0;
    3.  
    4. void SomeSyncRef()
    5. {
    6.     if ( 0 == g_SyncCounter ) {
    7.         ResetEvent(g_SyncEvent);
    8.     }
    9.     ++g_SyncCounter;
    10. }
    11.  
    12. void SomeSyncRelease()
    13. {
    14.     --g_SyncCounter;
    15.     if ( 0 == g_SyncCounter ) {
    16.         SetEvent(g_SyncEvent);
    17.     }
    18. }
    19.  
    20. BOOL SomeSyncWait(DWORD dwWaitTimeout)
    21. {
    22.     return WaitForSingleObject(g_SyncEvent, dwWaitTimeout) == WAIT_OBJECT_0 ? TRUE : FALSE;
    23. }
    Что сдесь сложного и не понятного?
     
  19. x64

    x64 New Member

    Публикаций:
    0
    Регистрация:
    29 июл 2008
    Сообщения:
    1.370
    Адрес:
    Россия
    А почему нельзя сначала посчитать кол-во необходимых потоков и только потом уже создавать их? Что за задача такая? Если потоки создаются только в точке входа процесса, где и происходит потом ожидание их завершения, то подсчитать необходимое их кол-во не должно вызывать никаких проблем. Если же дополнительные потоки могут порождать другие дополнительные потоки, то очевидно, стоит применить счётчик потоков и написать соответствующие функции типа Create/Delete, в Create - увеличивать счётчик, в Delete - уменьшать, при чём сразу после уменьшения проверять, если счётчик дошёл до нуля, то сигналить событие. Этого же события ждать перед выходом из точки входа. Я делал примерно также, когда надо было написать выгружаемый драйвер, который хукал много чего, - работало. Хотя для драйверов метод не 100% надёжный, сейчас другой использую, но тем не менее.
     
  20. _Juicy

    _Juicy Active Member

    Публикаций:
    0
    Регистрация:
    12 авг 2003
    Сообщения:
    1.159
    Адрес:
    SPb
    Для начала, мне непонятно, где здесь семафор.

    Количество потоков зависит от того, сколько раз пользователь - ну к примеру - кликнет по баттону.

    А, точно, к интерлоку добавить событие, тогда цикл не нужен. Хотя у меня можно и с циклом, основной поток начинает ждать дополнительные только при завершении.
    Все равно спасибо, пригодится на будущее.