Неверный дескриптор файла в pthread_detach - PullRequest
1 голос
/ 14 марта 2012

Мои вызовы pthread_detach завершаются с ошибкой «Bad file descriptor».Звонки в деструкторе для моего класса и выглядят так -

if(pthread_detach(get_sensors) != 0)
    printf("\ndetach on get_sensors failed with error %m", errno);

if(pthread_detach(get_real_velocity) != 0) 
    printf("\ndetach on get_real_velocity failed with error %m", errno);

Я только когда-либо имел дело с этой ошибкой при использовании сокетов.Что может быть причиной этого при вызове pthread_detach, который я должен искать?Или это может быть что-то в обратном вызове потока, что может быть причиной этого?На всякий случай, обратные вызовы выглядят так -

void* Robot::get_real_velocity_thread(void* threadid) {
    Robot* r = (Robot*)threadid;
    r->get_real_velocity_thread_i();
}

inline void Robot::get_real_velocity_thread_i() {
    while(1) {
        usleep(14500);

        sensor_packet temp = get_sensor_value(REQUESTED_VELOCITY);

        real_velocity = temp.values[0];
        if(temp.values[1] != -1)
            real_velocity += temp.values[1];
    }   //end while
}



/*Callback for get sensors thread*/
void* Robot::get_sensors_thread(void* threadid) {
    Robot* r = (Robot*)threadid;
    r->get_sensors_thread_i();
}   //END GETSENSORS_THREAD


inline void Robot::get_sensors_thread_i() {
    while(1) {

    usleep(14500);

    if(sensorsstreaming) {

        unsigned char receive;
        int read = 0;

        read = connection.PollComport(port, &receive, sizeof(unsigned char));

        if((int)receive == 19) {

            read = connection.PollComport(port, &receive, sizeof(unsigned char));

            unsigned char rest[54];

            read = connection.PollComport(port, rest, 54);

            /* ***SET SENSOR VALUES*** */
            //bump + wheel drop
            sensor_values[0] = (int)rest[1];
            sensor_values[1] = -1;
            //wall
            sensor_values[2] = (int)rest[2];
            sensor_values[3] = -1;
            ...
            ...
            lots more setting just like the two above
            }   //end if header == 19
        }   //end if sensors streaming
    }   //end while
}   //END GET_SENSORS_THREAD_I

Спасибо за любую помощь.

1 Ответ

1 голос
/ 20 марта 2012

Функции pthread_* возвращают код ошибки;они не устанавливают errno.(Ну, конечно, они могут, но никак не документировано.)

Ваш код должен распечатать значение, возвращаемое pthread_detach, и распечатать его.

Single Unix Spec документирует двавозвращаемые значения для этой функции: ESRCH (поток с этим идентификатором не найден) и EINVAL (поток не присоединяемый).

Отсоединение потоков в деструкторе объекта кажется глупым.Во-первых, если они в конечном итоге будут отсоединены, почему бы просто не создать их таким образом?

Если есть какой-либо риск того, что потоки могут использовать уничтожаемый объект, их нужно остановить, а не отсоединить,Т.е. вы как-то указываете потокам, что они должны закрыться, а затем ждете, пока они достигнут какого-то безопасного места, после которого они больше не будут касаться объекта.pthread_join полезен для этого.

Кроме того, уже немного поздно делать это с деструктором.Деструктор должен запускаться только тогда, когда выполняющий его поток является единственным потоком со ссылкой на этот объект.Если потоки все еще используют объект, вы уничтожаете его из-под них.

...