Здравствуйте, 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 то я не вижу смысла даже в критической секции.
Но опять же по необходимости, можна дописать все что угодно.