У меня есть поток, который читает сообщения из необработанного сокета HCI в цикле, подобном этому:
void* loop_hci (void* args) {
params_hci_t* params = (params_hci_t*) args;
int result_hci = 0;
uint8_t* buf_hci = calloc(1, HCI_EVENT_MAX_LENGTH);
while (!poll_end()) {
result_hci = read(params->hci_sock, buf_hci, HCI_EVENT_MAX_LENGTH);
if (result_hci > 0) {
// ... do stuff with the received data
}
}
ancs_pdebug("HCI loop shutting down...");
return NULL;
}
Функция poll_end()
работает нормально и по назначению. Он возвращает 0 до тех пор, пока не будет получен сигнал SIGINT, после чего возвращает 1.
В основном потоке я создаю сокет следующим образом:
hci_sock = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
А также ветка:
ph->hci_sock = hci_sock;
pthread_create(&t_hci, NULL, &loop_hci, ph);
Затем через некоторое время вызовите завершение работы следующим образом (в основном потоке):
shutdown(hci_sock, SHUT_RD);
Я предполагаю, что read() должен вернуться после того, как я вызову shutdown(), я использую тот же метод в другом потоке для сокета L2CAP, и он работает нормально. Но это не так. Мой вызов pthread_join(t_hci, NULL)
в основном потоке никогда не возвращается.
Розетка работает нормально. Я могу читать сообщения от него. Я также пытался вместо этого вызвать close (что я делаю после завершения потоков), но результаты такие же.
В чем может быть проблема, или мои предположения неверны?
read
на возврат0
или-1
? Еслиread
возвращает0
или-1
, прерываете ли вы цикл или иным образом завершаете поток? И, если возможно, попробуйте создать минимальный, полный и поддающийся проверке пример и покажите нам. - person Some programmer dude   schedule 30.05.2016shudown()
для дескриптора файла, используемого другим потоком, вообще разрешен? - person EOF   schedule 30.05.2016pthread_kill()
) или отменить потокpthread_cancel()
. Разумным способом было бы использовать[e]poll()
или[p]select()
на неблокирующем сокете. - person EOF   schedule 30.05.2016SHUT_RDWR
. - person Some programmer dude   schedule 30.05.2016shutdown()
ничего не делает только с сокетами TCP (SOCK_STREAM). Это сокет SOCK_RAW. @EOF Это вполне допустимый метод для сокетов TCP, но здесь это не сокет TCP. - person user207421   schedule 30.05.2016recv()
: чего он будет ждать? - person user207421   schedule 30.05.2016recv()
на ноль. Итак, как вы можете сказать, что он никогда не вернется? Откуда вы знаете, что это не просто зацикливание в вашем коде? - person user207421   schedule 30.05.2016shutdown()
для сокета, который используется другим потоком, не определен, тогда может произойти все что угодно. - person EOF   schedule 30.05.2016pthread_cancel()
-молотка является достойным подходом к решению этой проблемы. Если нет опроса/выбора, то отправьте потоку сигнал, используяpthread_kill()
, это приведет к возврату блокирующего системного вызова (здесьread()
) сerrno
, установленным вEINTR
(если в сокете не было установленоSA_RESTART
). Установите обработчик отправляемого вами сигнала. Ручка ничего не делала, а просто была рядом. - person alk   schedule 30.05.2016