Нить и СОМ порт
От: Владислав Россия  
Дата: 12.04.02 10:52
Оценка:
Открываю СОМ порт:

m_hCom = ::CreateFile("COM2:", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
                            FILE_ATTRIBUTE_NORMAL, NULL);


Провожу инициализацию ( на 90% уверен, что правильно). Создаю поток:

/*
   Параметры: 
   1. HANDLE h[2], где h[0] = m_hCom, h[1] = событие т.е. CreateEvent (...)
*/
   DWORD WINAPI Thread (LPVOID p)
   {
      HANDLE* h = (HANDLE*)p;
      while ((i = WaitForMultipleObjects (2, h, FALSE, INFINITE)) != 1)
      {
      }
      return 0;
   }


Когда выставляю h[1] т.е. SetEvent (в другом потоке само — собой), функция WaitForMultipleObjects начисто это игнорирует, хотя должна бы была возвратить 1, обеспечив выход из цикла и завершение потока. Почему?
Suum cuique (лат.)
Re: Нить и СОМ порт
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 12.04.02 11:00
Оценка:
Здравствуйте Владислав, Вы писали:

Com-порт здесь, скорее всего, не причем.
А как ты создаешь Event?
Re: Нить и СОМ порт
От: Кирпа В.А. Украина  
Дата: 12.04.02 11:01
Оценка:
Здравствуйте Владислав, Вы писали:


В>Открываю СОМ порт:


В>
В>m_hCom = ::CreateFile("COM2:", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
В>                            FILE_ATTRIBUTE_NORMAL, NULL);
В>


В>Провожу инициализацию ( на 90% уверен, что правильно). Создаю поток:


В>
В>/*
В>   Параметры: 
В>   1. HANDLE h[2], где h[0] = m_hCom, h[1] = событие т.е. CreateEvent (...)
В>*/
В>   DWORD WINAPI Thread (LPVOID p)
В>   {
В>      HANDLE* h = (HANDLE*)p;
В>      while ((i = WaitForMultipleObjects (2, h, FALSE, INFINITE)) != 1)
В>      {
В>      }
В>      return 0;
В>   }
В>


В>Когда выставляю h[1] т.е. SetEvent (в другом потоке само — собой), функция WaitForMultipleObjects начисто это игнорирует, хотя должна бы была возвратить 1, обеспечив выход из цикла и завершение потока. Почему?



Посмотри что возвращает WaitForMultipleObjects (выделено жирным)

Return Values
If the function succeeds, the return value indicates the event that caused the function to return. This value can be one of the following.

Value Meaning
WAIT_OBJECT_0 to (WAIT_OBJECT_0 + nCount – 1) If bWaitAll is TRUE, the return value indicates that the state of all specified objects is signaled.
If bWaitAll is FALSE, the return value minus WAIT_OBJECT_0 indicates the lpHandles array index of the object that satisfied the wait. If more than one object became signalled during the call, this is the array index of the signalled object with the smallest index value of all the signalled objects.
!0xDEAD
Re: Нить и СОМ порт
От: Sergey Россия  
Дата: 12.04.02 11:06
Оценка:
Здравствуйте Владислав, Вы писали:


В>Открываю СОМ порт:


В>
В>m_hCom = ::CreateFile("COM2:", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
В>                            FILE_ATTRIBUTE_NORMAL, NULL);
В>


В>Провожу инициализацию ( на 90% уверен, что правильно). Создаю поток:


В>
В>/*
В>   Параметры: 
В>   1. HANDLE h[2], где h[0] = m_hCom, h[1] = событие т.е. CreateEvent (...)
В>*/
В>   DWORD WINAPI Thread (LPVOID p)
В>   {
В>      HANDLE* h = (HANDLE*)p;
В>      while ((i = WaitForMultipleObjects (2, h, FALSE, INFINITE)) != 1)
В>      {
В>      }
В>      return 0;
В>   }
В>


В>Когда выставляю h[1] т.е. SetEvent (в другом потоке само — собой), функция WaitForMultipleObjects начисто это игнорирует, хотя должна бы была возвратить 1, обеспечив выход из цикла и завершение потока. Почему?


Вообще-то WAIT_FAILED == -1, а не 1, так что из цикла она выходить не должна. А возвращает она тебе скорее всего именно WAIT_FAILED, потому что хэнлы файлов ждать, согласно документации, не умеет (а кто вообще их умеет ждать?). И раз последний параметр у нее INFINITE, цикл там нафиг не нужен, а нужна нормальная обработка ошибок.
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re[2]: Нить и СОМ порт
От: Кирпа В.А. Украина  
Дата: 12.04.02 11:15
Оценка:
Здравствуйте Sergey, Вы писали:

S
В>> DWORD WINAPI Thread (LPVOID p)
В>> {
В>> HANDLE* h = (HANDLE*)p;
В>> while ((i = WaitForMultipleObjects (2, h, FALSE, INFINITE)) != 1)
В>> {
В>> }
В>> return 0;
В>> }
В>>[/code]

В>>Когда выставляю h[1] т.е. SetEvent (в другом потоке само — собой), функция WaitForMultipleObjects начисто это игнорирует, хотя должна бы была возвратить 1, обеспечив выход из цикла и завершение потока. Почему?


S>Вообще-то WAIT_FAILED == -1, а не 1, так что из цикла она выходить не должна. А возвращает она тебе скорее всего именно WAIT_FAILED, потому что хэнлы файлов ждать, согласно документации, не умеет (а кто вообще их умеет ждать?). И раз последний параметр у нее INFINITE, цикл там нафиг не нужен, а нужна нормальная обработка ошибок.


Так он же ждет один из хэндлов (третий параметр = FALSE) Так что наздороье!
Просто надо было написать вот так
while (1)
{
if ((i = WaitForMultipleObjects (2, h, FALSE, INFINITE) — WAIT_OBJECT_0) == 1)
break;
}
!0xDEAD
Re[3]: Нить и СОМ порт
От: Sergey Россия  
Дата: 12.04.02 11:33
Оценка:
Здравствуйте Кирпа В.А., Вы писали:

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


КВ>S

В>>> DWORD WINAPI Thread (LPVOID p)
В>>> {
В>>> HANDLE* h = (HANDLE*)p;
В>>> while ((i = WaitForMultipleObjects (2, h, FALSE, INFINITE)) != 1)
В>>> {
В>>> }
В>>> return 0;
В>>> }
В>>>[/code]

В>>>Когда выставляю h[1] т.е. SetEvent (в другом потоке само — собой), функция WaitForMultipleObjects начисто это игнорирует, хотя должна бы была возвратить 1, обеспечив выход из цикла и завершение потока. Почему?


S>>Вообще-то WAIT_FAILED == -1, а не 1, так что из цикла она выходить не должна. А возвращает она тебе скорее всего именно WAIT_FAILED, потому что хэнлы файлов ждать, согласно документации, не умеет (а кто вообще их умеет ждать?). И раз последний параметр у нее INFINITE, цикл там нафиг не нужен, а нужна нормальная обработка ошибок.


КВ>Так он же ждет один из хэндлов (третий параметр = FALSE) Так что наздороье!


Ага, шаз! Оно вообще не ждет — вываливается немедленно с WAIT_FAILED если любой из переданных хэндлов неправильный независимо от третьего параметра. По крайней мере, на моем компьютере.

КВ>Просто надо было написать вот так

КВ>while (1)
КВ>{
КВ> if ((i = WaitForMultipleObjects (2, h, FALSE, INFINITE) — WAIT_OBJECT_0) == 1)
КВ> break;
КВ>}

Это то же самое, вид сбоку. Правильно делать так:

    DWORD res;
    do
    {
        res = WaitForMultipleObjects(2, h, FALSE, mytimeout);
    } while (WAIT_TIMEOUT == res)
    switch (res)
    {
    ... обработка ошибок/событий
    }

Тогда, по крайней мере, потоки потом прибивать не придется.
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re[4]: Нить и СОМ порт
От: Кирпа В.А. Украина  
Дата: 12.04.02 11:46
Оценка:
Здравствуйте Sergey, Вы писали:

S>Здравствуйте Кирпа В.А., Вы писали:


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


КВ>>S

В>>>> DWORD WINAPI Thread (LPVOID p)
В>>>> {
В>>>> HANDLE* h = (HANDLE*)p;
В>>>> while ((i = WaitForMultipleObjects (2, h, FALSE, INFINITE)) != 1)
В>>>> {
В>>>> }
В>>>> return 0;
В>>>> }
В>>>>[/code]

В>>>>Когда выставляю h[1] т.е. SetEvent (в другом потоке само — собой), функция WaitForMultipleObjects начисто это игнорирует, хотя должна бы была возвратить 1, обеспечив выход из цикла и завершение потока. Почему?


S>>>Вообще-то WAIT_FAILED == -1, а не 1, так что из цикла она выходить не должна. А возвращает она тебе скорее всего именно WAIT_FAILED, потому что хэнлы файлов ждать, согласно документации, не умеет (а кто вообще их умеет ждать?). И раз последний параметр у нее INFINITE, цикл там нафиг не нужен, а нужна нормальная обработка ошибок.


КВ>>Так он же ждет один из хэндлов (третий параметр = FALSE) Так что наздороье!


S>Ага, шаз! Оно вообще не ждет — вываливается немедленно с WAIT_FAILED если любой из переданных хэндлов неправильный независимо от третьего параметра. По крайней мере, на моем компьютере.


КВ>>Просто надо было написать вот так

КВ>>while (1)
КВ>>{
КВ>> if ((i = WaitForMultipleObjects (2, h, FALSE, INFINITE) — WAIT_OBJECT_0) == 1)
КВ>> break;
КВ>>}

S>Это то же самое, вид сбоку. Правильно делать так:


S>
S>    DWORD res;
S>    do
S>    {
S>        res = WaitForMultipleObjects(2, h, FALSE, mytimeout);
S>    } while (WAIT_TIMEOUT == res)
S>    switch (res)
S>    {
S>    ... обработка ошибок/событий
S>    }
S>

S>Тогда, по крайней мере, потоки потом прибивать не придется.

Согласен что не надо ждать хендла порта (этот хэндл для WaitForMultipleObjects недопустим)
Я просто намекнул что проверять надо разницу WaitForMultipleObjects() — WAIT_OBJECT_0
Вот она и будет равна 1 когда второй хендл установится(то бишь когда сработает SetEvent)

!0xDEAD
Re[4]: Нить и СОМ порт
От: Кирпа В.А. Украина  
Дата: 12.04.02 11:46
Оценка:
Здравствуйте Sergey, Вы писали:

S>Здравствуйте Кирпа В.А., Вы писали:


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


КВ>>S

В>>>> DWORD WINAPI Thread (LPVOID p)
В>>>> {
В>>>> HANDLE* h = (HANDLE*)p;
В>>>> while ((i = WaitForMultipleObjects (2, h, FALSE, INFINITE)) != 1)
В>>>> {
В>>>> }
В>>>> return 0;
В>>>> }
В>>>>[/code]

В>>>>Когда выставляю h[1] т.е. SetEvent (в другом потоке само — собой), функция WaitForMultipleObjects начисто это игнорирует, хотя должна бы была возвратить 1, обеспечив выход из цикла и завершение потока. Почему?


S>>>Вообще-то WAIT_FAILED == -1, а не 1, так что из цикла она выходить не должна. А возвращает она тебе скорее всего именно WAIT_FAILED, потому что хэнлы файлов ждать, согласно документации, не умеет (а кто вообще их умеет ждать?). И раз последний параметр у нее INFINITE, цикл там нафиг не нужен, а нужна нормальная обработка ошибок.


КВ>>Так он же ждет один из хэндлов (третий параметр = FALSE) Так что наздороье!


S>Ага, шаз! Оно вообще не ждет — вываливается немедленно с WAIT_FAILED если любой из переданных хэндлов неправильный независимо от третьего параметра. По крайней мере, на моем компьютере.


КВ>>Просто надо было написать вот так

КВ>>while (1)
КВ>>{
КВ>> if ((i = WaitForMultipleObjects (2, h, FALSE, INFINITE) — WAIT_OBJECT_0) == 1)
КВ>> break;
КВ>>}

S>Это то же самое, вид сбоку. Правильно делать так:


S>
S>    DWORD res;
S>    do
S>    {
S>        res = WaitForMultipleObjects(2, h, FALSE, mytimeout);
S>    } while (WAIT_TIMEOUT == res)
S>    switch (res)
S>    {
S>    ... обработка ошибок/событий
S>    }
S>

S>Тогда, по крайней мере, потоки потом прибивать не придется.

Согласен что не надо ждать хендла порта (этот хэндл для WaitForMultipleObjects недопустим)
Я просто намекнул что проверять надо разницу WaitForMultipleObjects() — WAIT_OBJECT_0
Вот она и будет равна 1 когда второй хендл установится(то бишь когда сработает SetEvent)

!0xDEAD
Re[4]: Нить и СОМ порт
От: Кирпа В.А. Украина  
Дата: 12.04.02 11:46
Оценка:
Здравствуйте Sergey, Вы писали:

S>Здравствуйте Кирпа В.А., Вы писали:


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


КВ>>S

В>>>> DWORD WINAPI Thread (LPVOID p)
В>>>> {
В>>>> HANDLE* h = (HANDLE*)p;
В>>>> while ((i = WaitForMultipleObjects (2, h, FALSE, INFINITE)) != 1)
В>>>> {
В>>>> }
В>>>> return 0;
В>>>> }
В>>>>[/code]

В>>>>Когда выставляю h[1] т.е. SetEvent (в другом потоке само — собой), функция WaitForMultipleObjects начисто это игнорирует, хотя должна бы была возвратить 1, обеспечив выход из цикла и завершение потока. Почему?


S>>>Вообще-то WAIT_FAILED == -1, а не 1, так что из цикла она выходить не должна. А возвращает она тебе скорее всего именно WAIT_FAILED, потому что хэнлы файлов ждать, согласно документации, не умеет (а кто вообще их умеет ждать?). И раз последний параметр у нее INFINITE, цикл там нафиг не нужен, а нужна нормальная обработка ошибок.


КВ>>Так он же ждет один из хэндлов (третий параметр = FALSE) Так что наздороье!


S>Ага, шаз! Оно вообще не ждет — вываливается немедленно с WAIT_FAILED если любой из переданных хэндлов неправильный независимо от третьего параметра. По крайней мере, на моем компьютере.


КВ>>Просто надо было написать вот так

КВ>>while (1)
КВ>>{
КВ>> if ((i = WaitForMultipleObjects (2, h, FALSE, INFINITE) — WAIT_OBJECT_0) == 1)
КВ>> break;
КВ>>}

S>Это то же самое, вид сбоку. Правильно делать так:


S>
S>    DWORD res;
S>    do
S>    {
S>        res = WaitForMultipleObjects(2, h, FALSE, mytimeout);
S>    } while (WAIT_TIMEOUT == res)
S>    switch (res)
S>    {
S>    ... обработка ошибок/событий
S>    }
S>

S>Тогда, по крайней мере, потоки потом прибивать не придется.

Согласен что не надо ждать хендла порта (этот хэндл для WaitForMultipleObjects недопустим)
Я просто намекнул что проверять надо разницу WaitForMultipleObjects() — WAIT_OBJECT_0
Вот она и будет равна 1 когда второй хендл установится(то бишь когда сработает SetEvent)

!0xDEAD
Re[4]: Нить и СОМ порт
От: Владислав Россия  
Дата: 12.04.02 12:11
Оценка:
Здравствуйте Sergey, Вы писали:
...

Если параметром данной функции будет HANDLE h[2], где h[0] = CreateEvent (NULL, FALSE, FALSE, NULL); и h[1] анологично то если мы из другого потока выставим h[0] (SetEvent'ом) то сделаем один оборот цикла, если выставим h[1] — завершим поток.

   DWORD WINAPI Thread (LPVOID p)
   {
      int i = 0;
      HANDLE* h = (HANDLE*)p;
      while ((i = WaitForMultipleObjects (2, h, FALSE, INFINITE)) != 1)
      {
          afxDump << i << "\n";
      }
      return 0;
   }


У меня же h[0] — это HANDLE порта и я искренне верил, что в этом случае при поступлении в порт инфы функция вернёт 0, тем самым сделаем один оборот цикла, при установке h[1] функция вернёт 1 и поток завершится.
Видимо ошибался.

S>Ага, шаз! Оно вообще не ждет — вываливается немедленно с WAIT_FAILED если любой из переданных хэндлов неправильный независимо от третьего параметра. По крайней мере, на моем компьютере.

У меня не вываливается не вываливается.
Suum cuique (лат.)
Re[5]: Нить и СОМ порт
От: Владислав Россия  
Дата: 12.04.02 12:15
Оценка:
Чтож, воспользуюсь WaitCommEvent и не буду забивать мозги ни себе ни вам.
Всем спасибо.
Suum cuique (лат.)
Re[5]: Нить и СОМ порт
От: Sergey Россия  
Дата: 12.04.02 12:25
Оценка:
Здравствуйте Владислав, Вы писали:

В>У меня же h[0] — это HANDLE порта и я искренне верил, что в этом случае при поступлении в порт инфы функция вернёт 0, тем самым сделаем один оборот цикла, при установке h[1] функция вернёт 1 и поток завершится.

В>Видимо ошибался.
Угу.

S>>Ага, шаз! Оно вообще не ждет — вываливается немедленно с WAIT_FAILED если любой из переданных хэндлов неправильный независимо от третьего параметра. По крайней мере, на моем компьютере.

В>У меня не вываливается не вываливается.

Не вываливается из функции или не вываливается из цикла? Если первое, то какая операционка?
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re[6]: Нить и СОМ порт
От: Владислав Россия  
Дата: 12.04.02 12:48
Оценка:
Здравствуйте Sergey, Вы писали:

S>Не вываливается из функции или не вываливается из цикла? Если первое, то какая операционка?

Из функции вываливается но не с WAIT_FAILED а с номером HANDLE порта, в данном случае 0. Удивительно то, что функция ReadFile (h[0],...) в теле цикла возвращает прочитанные байты
Операционка Windows XP.
Да кстати:

#define WAIT_OBJECT_0       ((STATUS_WAIT_0 ) + 0 ) // winbase.h
#define STATUS_WAIT_0       ((DWORD   )0x00000000L) // winnt.h
Suum cuique (лат.)
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.