Re[8]: блокировка трэда
От: Alexmoon Украина  
Дата: 28.02.05 08:15
Оценка:
Здравствуйте, Delphi, Вы писали:

D>Здравствуйте, Alexmoon, Вы писали:



A>>9. В методе добавления элемента в список, в самом конце выставление события в сигнальное состояние.

A>>10.В методе извлечения в конце с проверкой очереди на пустоту сбрасывание, если элементов нет.

D>Предположим, что кол-во элементов нам известно(для упрощения схемы). Пусть их будет, например, 5. =>


D>
D>.........
D>HANDLE hEvent; // глобальная переменная, так же как и thread;
D>.........
D>i = 0;
D>while (i < 5) {
D>     hEvent = CreateEvent(NULL, false, false, "asda");

D>     thread = AfxBeginThread((AFX_THREADPROC)  Our_Func, 
D>                element[i], 
D>                THREAD_PRIORITY_NORMAL, 
D>                0, 
D>                0, 
D>                NULL);
D>     SetEvent(hEvent); // выставляем событие в сигнальное состояние, чтобы Our_Func запустилась 
D>     ResetEvent(hEvent); // сбрасываем событие
D>i++;

D>}
D>.............

D>...Our_func..() 
D>{
D>     WaitForSingleObject(hEvent,INFINITE); // ожидаем сигнала
D>     ................
     
D>     ................
D>     SetEvent(hEvent);
D>     return true;
D>}

D>


D>Так вот, если у нас всего 2 элемента, то все хорошо, однако при большем количестве накапливается куча ожидающих своего часа событий, и как только 1-й завершившийся трэд делает SetEvent(hEvent), они все дружно просыпаются...., можно конечно в цикл запихать WaitForSingleObject(hEvent,INFINITE), но тогда смысл трэдов теряется.

D>Да и с SetEvent(hEvent) внутри цикла нужно что-то делать, т.к. это неправильно, да и по логике работать не должно

Предположим, что кол-во элементов нам известно(для упрощения схемы). Пусть их будет, например, 5. =>

как это облегчает суть решения задачи?

хорошо. обо всем по порядку.

1. О каком SetEvent идет речь внутри рабочего цикла ожидания. Это принципиально неправильно и об это даже речи не шло.
2. SetEvent должен быть только за методом AddEventHandler в реализации объекта PostEventHandler и то я там не уточнил, что его нужно делать в конце метода, после добавления нового элемента с проверкой количества элементов равным 1. Но это легко укладывается в раздел уточнения по ходу реализации.
3. Суть работы механизма — это изоляция работы механизма GUI и его реализации. Если у тебя все обработчики должны работать последовательно, то накой тебе заготовки под все потоки, где смысл в расходе памяти под структуры потока. Как сказал один умный человек они тоже не воздушные. В этом есть смысл только при условии, что хоть часть работы будет выполняться параллельно, да и для этого вполне подходит потоков. Особенности синхронизации при этом ложаться на плечи обработчиков под каждый поток в пуле.
4. Привеленные выше мои слова неужели намекают на подобную реализацию?

...Our_func..() 
{
     WaitForSingleObject(hEvent,INFINITE); // ожидаем сигнала
     ................
     
     ................
     SetEvent(hEvent);
     return true;
}

5. Теперь по цитатам.

Разумеется нам ненадо делать 300 коннектингов к серверу, и мы создаем очередь

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

функцию потока придется наверное привести
...Our_func..() 
{
     while(true)
     {
          if(WaitForSingleObject(hEventExit, 0)    != WAIT_TIMEOUT)  break;
          if(WaitForSingleObject(hEvent, INFINITE) != WAIT_OBJECT_0) break;
          HPARAM _param = GetEvent();
          ................
     }
     CloseHandle(hEventExit);
     CloseHandle(hEvent);
     return 0;
}
AddEvent(const HPARAM& param)
{
     queue_ref.push_back(param);
     if(queue.size == 1) SetEvent(hEvent);
}
HPARAM GetEvent()
{ 
     HPARAM _param = queue.pop();
     if(queue_ref.size == 0) ResetEvent(hEvent);
}
~destructor()
{
    SetEvent(hEventExit);
}


abstract idea.
писал на колене, по этому на синтаксис внимания не обращай.
так как это обработка GUI то я не вижу смысла даже в критической секции.
Но опять же по необходимости, можна дописать все что угодно.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.