Последовательность работы потоков...

Тема в разделе "WASM.WIN32", создана пользователем Trashy, 24 дек 2004.

  1. Trashy

    Trashy New Member

    Публикаций:
    0
    Регистрация:
    24 дек 2004
    Сообщения:
    44
    Адрес:
    Russia
    У меня создаётся несколько потоков (п1,п2,п3). Иногда случаются моменты, когда несколько потоков пытаются захватить закрытый объект синхронизации (Mutex например). Так, вот, есть ли какой-либо метод в операционной системе, что бы, при переходе Мутекса в сигнальное состояние, потокам передавалось управление в той последовательности в какой они захватывали объект синхронизации?
     
  2. shoo

    shoo New Member

    Публикаций:
    0
    Регистрация:
    17 июл 2003
    Сообщения:
    1.537
    Адрес:
    Ukraine
    наверное, нет: когда-то я писал самработу и запустил около десятка экземпляров программ, которые пытались захватить один мьютекс, так хватали только первые два, изредка - третий. остальные - отдыхали. так что я понял, что они вызываются каждый раз по списку с начала.

    правда, платформа была: win95/486dlc-40, а проги отпускали мьютекс и сразу же пытались его захватить.
     
  3. EvilsInterrupt

    EvilsInterrupt Постигающий азы дзена

    Публикаций:
    0
    Регистрация:
    28 окт 2003
    Сообщения:
    2.428
    Адрес:
    Russia
    Обедающие философы у Таненбаума, shoo ты это хотел сказать?
     
  4. shoo

    shoo New Member

    Публикаций:
    0
    Регистрация:
    17 июл 2003
    Сообщения:
    1.537
    Адрес:
    Ukraine
    Ох, философы устали за неделю! ща одна проблема - машину рядом с домом поставить или в гараже хрен знает где?.. а вдруг завтра на морозе не заведется! может, топик создать - насоветуют чего :)
     
  5. NoName

    NoName New Member

    Публикаций:
    0
    Регистрация:
    1 авг 2004
    Сообщения:
    1.229
    Кстати говоря на 2000 засуне и старше сделано распределение мьютекса между потоками таким образом, чтобы избежать вот этой проблемы:

     
  6. NoName

    NoName New Member

    Публикаций:
    0
    Регистрация:
    1 авг 2004
    Сообщения:
    1.229
    Точный механизм микробы не описывают, но там что-то вроде рандома с искуственным интелектом.
     
  7. NoName

    NoName New Member

    Публикаций:
    0
    Регистрация:
    1 авг 2004
    Сообщения:
    1.229


    Напиши чуть яснее, боюсь ошибиться.
     
  8. Sten

    Sten New Member

    Публикаций:
    0
    Регистрация:
    2 июн 2003
    Сообщения:
    39
    > Точный механизм микробы не описывают, но там что-то вроде рандома с искуственным интелектом



    Браво! В цитатник.. :)
     
  9. Trashy

    Trashy New Member

    Публикаций:
    0
    Регистрация:
    24 дек 2004
    Сообщения:
    44
    Адрес:
    Russia
    Код (Text):
    1. „потокам передавалось управление в той последовательности в какой они захватывали объект синхронизации?“
    2. Напиши чуть яснее, боюсь ошибиться.




    Да. Криво. Должно быть так:

    „потокам передавалось управление в той последовательности в какой они пытаются захватить объект синхронизации?“

    То есть, владельцем мутекса может быть только один. А остальные "спят". Как только освобождается мутекс, один из потоков просыпается и захватывает мутекс, только проснуться должен тот поток который, наткнувшись на закрытый мутекс, "уснул" первым.
     
  10. NoName

    NoName New Member

    Публикаций:
    0
    Регистрация:
    1 авг 2004
    Сообщения:
    1.229
    2 Trashy

    Я думаю это реально сделать не средставми системы (поскольку таковых нет), но вручную. Например заводишь глобальную переменную и т.п.



    А для чего тебе это надо?
     
  11. EvilsInterrupt

    EvilsInterrupt Постигающий азы дзена

    Публикаций:
    0
    Регистрация:
    28 окт 2003
    Сообщения:
    2.428
    Адрес:
    Russia
    >топик создать - насоветуют чего :)



    :)))

    Мудро!
     
  12. shoo

    shoo New Member

    Публикаций:
    0
    Регистрация:
    17 июл 2003
    Сообщения:
    1.537
    Адрес:
    Ukraine
    Trashy

    вот, набросал кой чего - на большее времени нет :dntknw:

    Вариант для потоков одного процесса с кольцевой очередью на 256 потоков.

    Используется два мьютекса - один для дела, и один - для доступа

    к очереди.

    Количество потоков не проверяется - при превышении могут появиться

    потоки, уснувшие навечно ;) - в этом случае или вводится контроль, или

    расширяется очередь.

    В случае разных процессов можно использовать memory mapped file для очереди.

    для данного механизма наследование хэндлов обязательно!



    смысл в том, что текущий владелец мьютекса освобождает его, если пуста очередь

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

    мьютекса. таким образом все желающие завладеть мьютексом вынуждены становиться в очередь,

    пока она непуста...


    Код (Text):
    1.  
    2. .data?
    3. ; общие данные
    4. queue       dd 256 dup(?)
    5.  
    6. ; индивидуальные данные для потока
    7. pid         dd ?
    8. hMutex_q    dd ?
    9. hMutex_m    dd ?
    10.  
    11. .data
    12. ; общие данные
    13. q_in        db 0
    14. q_out       db 0
    15.  
    16. .code
    17.  
    18.     ...
    19. @@:
    20.     invoke OpenMutex,... ; попытка захватить главный мьютекс без ожидания
    21.     test eax,eax
    22.     jnz @F
    23.     invoke OpenMutex,... ; захват мьютекса доступа к очереди с ожиданием
    24.     mov hMutex_q,eax
    25.     movzx eax,q_in
    26.     mov ecx,pid
    27.     lea eax,queue[eax*4]
    28.     mov [eax],ecx   ; записываем пид данного потока в очередь
    29.     inc q_in        ; увеличиваем указатель очереди для записи
    30.     push eax              
    31.     invoke ReleaseMutex,hMutex_q ; отпускаем мьютекс очереди перед сном
    32.     invoke SuspendThread,pid ; останавливаем данный поток
    33.     pop eax
    34.     mov eax,[eax]   ; извлекаем хэндл мьютекса
    35. @@:
    36. ;-------------------------- главный мьютекс захвачен!
    37.     mov hMutex_m,eax
    38.     .
    39.     .
    40.     .
    41.     invoke OpenMutex,... ; захват мьютекса доступа к очереди с ожиданием
    42.     mov hMutex_q,eax
    43.     movzx eax,q_out      ; пуста ли очередь?
    44.     cmp al,q_in
    45.     je @F                ; если да - то вперед
    46.     lea eax,queue[eax*4] ; получаем адрес в очереди
    47.     mov ecx,hMutex_m
    48.     xchg ecx,[eax]       ; заменяем в очереди пид потока на хэндл главного мьютекса
    49.     inc q_out            ; увеличиваем указатель очереди для чтения
    50.     invoke ResumeThread,ecx ; запускаем поток первый из очереди
    51.     jmp d_exit
    52. @@:
    53.     invoke ReleaseMutex,hMutex_m ; отпускаем главный мьютекс
    54. d_exit:
    55.     invoke ReleaseMutex,hMutex_q ; отпускаем мьютекс очереди
    56.     ...
     
  13. shoo

    shoo New Member

    Публикаций:
    0
    Регистрация:
    17 июл 2003
    Сообщения:
    1.537
    Адрес:
    Ukraine
    (не, не годится - подумаем еще...) вроде поправил ;)
     
  14. Black_mirror

    Black_mirror Active Member

    Публикаций:
    0
    Регистрация:
    14 окт 2002
    Сообщения:
    1.035
    Если первый поток захватит главный Mutex когда очередь пуста, а потом вдруг уснёт после выполнения cmp al,q_in и в этот момент второй поток попытается добавить себя в очередь, то второй поток уснёт, а кто-то другой сможет захватит главный Mutex вне очереди.
     
  15. shoo

    shoo New Member

    Публикаций:
    0
    Регистрация:
    17 июл 2003
    Сообщения:
    1.537
    Адрес:
    Ukraine
    да надо будет за машиной попробовать - я это обдумывал, когда рыбу чистил ;)
     
  16. Trashy

    Trashy New Member

    Публикаций:
    0
    Регистрация:
    24 дек 2004
    Сообщения:
    44
    Адрес:
    Russia
    NoName

    А, заводить глобальную переменную, не очень красиво. Это поток просыпается(захватывает объект), смотрит его ли очередь и если не его - освобождает объект и Sleep(0);...

    Это просто, но это переключение контекстов. А если потоков 10! Или двадцать! Или... Да хер его знает сколько пользователей приконнектится может...

    Это сколько же Sleep'ов произойдёт пока нужный поток не подключится? Причём вызвав Sleep я не могу вызвать WaitForSingleObject, так как мутекс открыт. И так придётся вызывать Sleep до тех пор, пока не поймаю нужный поток!



    А есть метод получения количества спящих объектов на мутексе?

    Есть гденить инфа о практическом применений extended alertable function (SleepEx или WaitForSingleObjectEx)?

    У меня просто работа с асинхронным-IO связана.



    Зачем мне это?

    Что бы знать как это всё работает.

    Уже почти всего Рихтера перерыл, а ответа найти не могу.
     
  17. shoo

    shoo New Member

    Публикаций:
    0
    Регистрация:
    17 июл 2003
    Сообщения:
    1.537
    Адрес:
    Ukraine
    нужно писать диспетчер, работающий как мьютекс, но так как надо. механизм, который я привел, имеет сущ. недостаток - если текущий поток скоропостижно отбросит копыта, то вся очередь будет спокойно спать до завершения процесса (хотя и на этот случай мысли наклевываются, но пока неясные)

    sleep - не очень хороший вариант - нужна четкая остановка и запуск потоков согласно очереди.

    насчет инфы: не вся полная и ясная - все нужно пробовать.