std::vector<HANDLE> как аргумент WaitForMultipleObjects()
От: Аноним  
Дата: 02.09.05 11:00
Оценка:
Используется функция WaitForMultipleObjects(...), скажем для 10-ти объектов (для ВСЕХ объектов):

HANDLE Array[10];
WaitForMultipleObjects(10, Array, TRUE, INFINITE);

Возможно ли, если да, то как, использовать вместо массива Array[] контейнер std::vector<HANDLE>? Что подставлять во второй параметр функции WaitForMultipleObjects(...)?
Re: std::vector<HANDLE> как аргумент WaitForMultipleObjects(
От: Gleb Alexeev  
Дата: 02.09.05 11:03
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Используется функция WaitForMultipleObjects(...), скажем для 10-ти объектов (для ВСЕХ объектов):


А>HANDLE Array[10];

А>WaitForMultipleObjects(10, Array, TRUE, INFINITE);

А>Возможно ли, если да, то как, использовать вместо массива Array[] контейнер std::vector<HANDLE>? Что подставлять во второй параметр функции WaitForMultipleObjects(...)?



std::vector<HANDLE> handles;
...
WaitForMultipleObjects(10, &handles[0], TRUE, INFINITE);
Re: std::vector<HANDLE> как аргумент WaitForMultipleObjects(
От: Кодт Россия  
Дата: 02.09.05 11:10
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Используется функция WaitForMultipleObjects(...), скажем для 10-ти объектов (для ВСЕХ объектов):


А>HANDLE Array[10];

А>WaitForMultipleObjects(10, Array, TRUE, INFINITE);

А>Возможно ли, если да, то как, использовать вместо массива Array[] контейнер std::vector<HANDLE>? Что подставлять во второй параметр функции WaitForMultipleObjects(...)?


unsigned WaitForMultipleObjects(std::vector<HANDLE> const& handles, bool wait_all, unsigned timeout)
{
  return WaitForMultipleObjects(handles.size(), &handles[0], wait_all, timeout);
}
Перекуём баги на фичи!
Re: std::vector<HANDLE> как аргумент WaitForMultipleObjects(
От: Кодт Россия  
Дата: 02.09.05 11:16
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Используется функция WaitForMultipleObjects(...), скажем для 10-ти объектов (для ВСЕХ объектов):


Кстати говоря. Неплохо бы ещё проверять, что размер массива|вектора не превосходит MAXIMUM_WAIT_OBJECTS.
Если превосходит, то можно сделать последовательное ожидание в несколько заходов. При этом нужно немножко повыделываться с таймаутом.
Перекуём баги на фичи!
Re[2]: std::vector<HANDLE> как аргумент WaitForMultipleObjec
От: Аноним  
Дата: 02.09.05 11:18
Оценка:
Здравствуйте, Gleb Alexeev, Вы писали:

GA>Здравствуйте, Аноним, Вы писали:


А>>Используется функция WaitForMultipleObjects(...), скажем для 10-ти объектов (для ВСЕХ объектов):


А>>HANDLE Array[10];

А>>WaitForMultipleObjects(10, Array, TRUE, INFINITE);

А>>Возможно ли, если да, то как, использовать вместо массива Array[] контейнер std::vector<HANDLE>? Что подставлять во второй параметр функции WaitForMultipleObjects(...)?



GA>
GA>std::vector<HANDLE> handles;
GA>...
GA>WaitForMultipleObjects(10, &handles[0], TRUE, INFINITE); 

GA>


Да, так работает. А, так нет:

std::vector<HANDLE> handles;
...
WaitForMultipleObjects(10, handles, TRUE, INFINITE);

пишет: cannot convert parameter 2 from std::vector<HANDLE> to const HANDLE*


хотя для простого массива оба варианта корректны:
WaitForMultipleObjects(10, Array, TRUE, INFINITE);

и

А>>WaitForMultipleObjects(10, &Array[0], TRUE, INFINITE);
Re[3]: std::vector<HANDLE> как аргумент WaitForMultipleObjec
От: Gleb Alexeev  
Дата: 02.09.05 11:26
Оценка:
Здравствуйте, Аноним, Вы писали:

А>пишет: cannot convert parameter 2 from std::vector<HANDLE> to const HANDLE*


Пишет правду, вектор, в отличие от массива, неявно (да и явно тоже) к указателю на элемент преобразования не имеет. Хочется простого синтаксиса — можно добавить перегрузку, как советовал Кодт.
Re[2]: std::vector<HANDLE> как аргумент WaitForMultipleObjec
От: Gleb Alexeev  
Дата: 02.09.05 11:32
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Кстати говоря. Неплохо бы ещё проверять, что размер массива|вектора не превосходит MAXIMUM_WAIT_OBJECTS.

К>Если превосходит, то можно сделать последовательное ожидание в несколько заходов. При этом нужно немножко повыделываться с таймаутом.

Последовательное ожидание -- как-то сильно неэквивалентно исходной задаче (было бы эквивалентно, функция WaitForMultipleObjects была бы не нужна).
Сам не пробовал, но добрые люди (и Рихтер в том числе) пишут, что лучше в таком случае создать несколько потоков, каждый из которых будет дожидаться подмножество хэндлов, а на верхнем уровне дожидаться завершения потоков.

У Рихтера даже демка есть такая, причем с произвольным логическим выражением (конъюнкция/дизъюнкция подмножеств хэндлов).
Re[2]: std::vector<HANDLE> как аргумент WaitForMultipleObjec
От: rus blood Россия  
Дата: 02.09.05 11:33
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Кстати говоря. Неплохо бы ещё проверять, что размер массива|вектора не превосходит MAXIMUM_WAIT_OBJECTS.

К>Если превосходит, то можно сделать последовательное ожидание в несколько заходов. При этом нужно немножко повыделываться с таймаутом.

Каким образом?
Имею скафандр — готов путешествовать!
Re[3]: std::vector<HANDLE> как аргумент WaitForMultipleObjec
От: Кодт Россия  
Дата: 02.09.05 11:48
Оценка:
Здравствуйте, Gleb Alexeev, Вы писали:

GA>Последовательное ожидание -- как-то сильно неэквивалентно исходной задаче (было бы эквивалентно, функция WaitForMultipleObjects была бы не нужна).


Смотря что хочется добиться.

Во-первых, разумеется — дизъюнкцию через последовательность выразить проблематично. (Можно, конечно, нарезать таймаут на приемлемые маленькие отрезки и покрутить всё это в цикле). Конъюнкция же через последовательность выражается.

Во-вторых, таким способом можно ждать только объекты, не меняющие своего состояния под действием ожидания. То есть
— события
— overlapped i/o
— завершение потоков
Номер не пройдёт для
— мьютексов (которые захватываются при удачном ожидании): в случае, если частичное ожидание успешно, а полное нет, нужно будет отпустить ошибочно захваченные объекты
— и ещё есть вопрос про автоматически сбрасываемые события.

GA>Сам не пробовал, но добрые люди (и Рихтер в том числе) пишут, что лучше в таком случае создать несколько потоков, каждый из которых будет дожидаться подмножество хэндлов, а на верхнем уровне дожидаться завершения потоков.


В общем-то, какая разница, как распределить ожидание: одним потоком последовательно или несколькими параллельно. Разве что дизъюнкцию проще реализовать.
Ну и накладные расходы: создание потоков. Впрочем, ради такого дела можно ввести пул потоков...

Но лучше задать себе вопрос: какого лешего я жду столько объектов сразу? И вообще, почему встал вопрос об ожидании переменного числа объектов?
То есть, пересмотреть дизайн программы.
Перекуём баги на фичи!
Re[3]: std::vector<HANDLE> как аргумент WaitForMultipleObjec
От: aik Австралия  
Дата: 02.09.05 11:57
Оценка:
Здравствуйте, Аноним, Вы писали:

А>>>Используется функция WaitForMultipleObjects(...), скажем для 10-ти объектов (для ВСЕХ объектов):

А>>>HANDLE Array[10];
А>>>WaitForMultipleObjects(10, Array, TRUE, INFINITE);
А>>>Возможно ли, если да, то как, использовать вместо массива Array[] контейнер std::vector<HANDLE>? Что подставлять во второй параметр функции WaitForMultipleObjects(...)?
GA>>
GA>>std::vector<HANDLE> handles;
GA>>...
GA>>WaitForMultipleObjects(10, &handles[0], TRUE, INFINITE); 

GA>>


А>Да, так работает. А, так нет:

А>std::vector<HANDLE> handles;
А>...
А>WaitForMultipleObjects(10, handles, TRUE, INFINITE);
А>пишет: cannot convert parameter 2 from std::vector<HANDLE> to const HANDLE*

Тебе одного способа мало? Работает же. Вектор != массив, то что работает как &r[0] — уже хорошо.
Только вместо 10 правильнее писать что то типа handles.count() (или как там количество элементов вектора взять).
Re[4]: std::vector<HANDLE> как аргумент WaitForMultipleObjec
От: Gleb Alexeev  
Дата: 02.09.05 12:02
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Но лучше задать себе вопрос: какого лешего я жду столько объектов сразу? И вообще, почему встал вопрос об ожидании переменного числа объектов?

К>То есть, пересмотреть дизайн программы.

Если не ошибаюсь, задачу ожидания объектов синхронизации количеством > MAX_WAIT_OBJECTS поставили именно Вы , original poster'у ножно было только 10.

С уважением,
Re[4]: std::vector<HANDLE> как аргумент WaitForMultipleObjec
От: Аноним  
Дата: 02.09.05 12:09
Оценка:
Здравствуйте, aik, Вы писали:

aik>Только вместо 10 правильнее писать что то типа handles.count() (или как там количество элементов вектора взять).


размер контейнера vector берется так: handles.size()

WaitForMultipleObjects(handles.size(), &handles[0], TRUE, INFINITE);

но при этом возвращается тип size_t, а ожидается тип DWORD. Соответственно, компилятор выдает предупреждение:

C4267: conversion from size_t to DWORD, ....

конечно, в данном случае, это не важно, но как лучше привести тип:

static_cast<DWORD> (handles.size())

или

(DWORD) handles.size()

???
Re[3]: std::vector<HANDLE> как аргумент WaitForMultipleObjec
От: Кодт Россия  
Дата: 02.09.05 12:09
Оценка:
Здравствуйте, rus blood, Вы писали:

RB>Здравствуйте, Кодт, Вы писали:


К>>Кстати говоря. Неплохо бы ещё проверять, что размер массива|вектора не превосходит MAXIMUM_WAIT_OBJECTS.

К>>Если превосходит, то можно сделать последовательное ожидание в несколько заходов. При этом нужно немножко повыделываться с таймаутом.

RB>Каким образом?


Если таймаут нулевой или бесконечный, то просто нарежем массив на подмассивы и последовательно подождём с нулевым или бесконечным соответственно.
Если таймаут конечный, то нужно засечь текущее время и указывать каждому подмассиву таймаут до точки общего финиша (приближающейся с каждым разом).
bool wait_all_limited(const HANDLES* handles, size_t size, unsigned timeout);

bool wait_all(const HANDLES* handles, size_t size, unsigned timeout)
{
  bool freetime = timeout==0 || timeout==INFINITE;
  unsigned start = freetime ? 0 : GetTickCount(); // финиш запланирован на start+timeout
  for(unsigned i=0; i<size; i+=MAXIMUM_WAIT_OBJECTS)
  {
    unsigned now = freetime ? 0 : GetTickCount() - start; // сделано с учётом беззнаковой арифметики
    if(now > timeout) return false;
    bool wait = wait_all_limited(handles+i, min(size-i,MAXIMUM_WAIT_OBJECTS), timeout-now);
    if(!wait) return false;
  }
  return true;
}


Кроме того, может потребоваться ловля WAIT_ABANDONED_n... Тут проверок будет поболее...
Перекуём баги на фичи!
Re[5]: std::vector<HANDLE> как аргумент WaitForMultipleObjec
От: Аноним  
Дата: 02.09.05 12:10
Оценка:
Здравствуйте, Gleb Alexeev, Вы писали:

GA>Здравствуйте, Кодт, Вы писали:


К>>Но лучше задать себе вопрос: какого лешего я жду столько объектов сразу? И вообще, почему встал вопрос об ожидании переменного числа объектов?

К>>То есть, пересмотреть дизайн программы.

GA>Если не ошибаюсь, задачу ожидания объектов синхронизации количеством > MAX_WAIT_OBJECTS поставили именно Вы , original poster'у ножно было только 10.


GA>С уважением,



Да, это количество контролируется в другом месте, и не может быть, в принципе, > 128
Re[6]: std::vector<HANDLE> как аргумент WaitForMultipleObjec
От: Gleb Alexeev  
Дата: 02.09.05 12:16
Оценка: +1
Здравствуйте, Аноним, Вы писали:


А>Да, это количество контролируется в другом месте, и не может быть, в принципе, > 128

Из установленного вместе с 2003-й студией Platform SDK:

#define MAXIMUM_WAIT_OBJECTS 64     // Maximum number of wait objects
Re[5]: std::vector<HANDLE> как аргумент WaitForMultipleObjec
От: Кодт Россия  
Дата: 02.09.05 12:22
Оценка: +1
Здравствуйте, Gleb Alexeev, Вы писали:

GA>Если не ошибаюсь, задачу ожидания объектов синхронизации количеством > MAX_WAIT_OBJECTS поставили именно Вы , original poster'у ножно было только 10.


Где десять, там и сто. Уже тот факт, что массив ожидания не набирается по месту
HANDLE handles[] = { hMyFirstObject, hMyAnotherObject, hSomethingElse };
WaitForMultipleObjects(3, handles, timeout);

а создаётся динамически и бывает переменной длины — должен настораживать.
Перекуём баги на фичи!
Re[4]: std::vector<HANDLE> как аргумент WaitForMultipleObjec
От: rus blood Россия  
Дата: 02.09.05 13:07
Оценка:
Здравствуйте, Кодт, Вы писали:

Это если ждем срабатывания всех ивентов. Я не посмотрел исходный пост внимательно...

А если нужно ждать произвольного ивента? Т.е. bWaitAll=FALSE...
Имею скафандр — готов путешествовать!
Re[5]: std::vector<HANDLE> как аргумент WaitForMultipleObjec
От: Кодт Россия  
Дата: 02.09.05 13:49
Оценка:
Здравствуйте, rus blood, Вы писали:

RB>Это если ждем срабатывания всех ивентов. Я не посмотрел исходный пост внимательно...


RB>А если нужно ждать произвольного ивента? Т.е. bWaitAll=FALSE...


Тогда всё сложнее. Либо раскидываем на несколько потоков, либо молотим цикл ожидания с нулевыми таймаутами и засыпанием на короткое время.
Перекуём баги на фичи!
Re: std::vector<HANDLE> как аргумент WaitForMultipleObjects(
От: Ally235 Россия  
Дата: 02.09.05 21:18
Оценка: -3
Здравствуйте, Аноним, Вы писали:

А>Используется функция WaitForMultipleObjects(...), скажем для 10-ти объектов (для ВСЕХ объектов):


А>HANDLE Array[10];

А>WaitForMultipleObjects(10, Array, TRUE, INFINITE);

А>Возможно ли, если да, то как, использовать вместо массива Array[] контейнер std::vector<HANDLE>? Что подставлять во второй параметр функции WaitForMultipleObjects(...)?


Чтобы так делать, надо удостовериться в том что vector внутри хранит свои элементы в виде массива. Вам охота разбираться в реализации vector в Вашей версии STL?
Я в таких случаях boost::scoped_array использую...
всё есть брахман
Re[2]: std::vector<HANDLE> как аргумент WaitForMultipleObjec
От: _nn_ www.nemerleweb.com
Дата: 03.09.05 07:28
Оценка:
Здравствуйте, Ally235, Вы писали:

A>Чтобы так делать, надо удостовериться в том что vector внутри хранит свои элементы в виде массива.


Стандарт гарантирует
http://rsdn.nemerleweb.com
http://nemerleweb.com
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.