2016-10-04 10 views
1

저는 libusb를 처음 사용하므로 잘 이해하지 못합니다. USB 통신을하려고합니다.C++ 11 비동기 사용시 Libusb가 응답하지 않습니다.

아주 잘 작동하는 핫 플러그 ​​기능을 사용하고 있습니다. 그래서 나는 장치가 도착한 이벤트를 감지했을 때 C++11 비동기 기능을 사용하는 다른 스레드에서 USB와의 모든 통신을 수행 할 것이므로 단순히 여러 장치로 동기 I/O를 수행 할 수있었습니다. 비동기 I/O는 다소 혼란 스럽습니다. 다행스럽게도 동기 I/O를 C++ 비동기 기능과 함께 사용할 수 있습니다.

하지만 코드가 C++ 11 비동기 기능에서 실행될 때 libusb 호출이 멈추는 문제가 있습니다. C++ 11 비동기 기능에서 실행되지 않을 때는 문제없이 작동합니다.

그래서 내 C++ 11 비동기 기능 코드가 문제라고 가정합니다.

Opening 
Opened 
Closing 

주요 코드는 다음과 같습니다 :

int main(int argc, char* argv[]) { 

    int vendor_id = 0x1234; 
    int product_id = 0x4556; 

    libusb_hotplug_callback_handle *hp = nullptr; 
    libusb_context *context = nullptr; 
    int rc = libusb_init(&context); 

    if(rc < 0) 
    { 
    return rc; 
    } 

    libusb_set_debug(context, LIBUSB_LOG_LEVEL_WARNING); 

    rc = libusb_hotplug_register_callback(
    context, 
    LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED, 
    LIBUSB_HOTPLUG_NO_FLAGS, 
    vendor_id, 
    product_id, 
    LIBUSB_HOTPLUG_MATCH_ANY, 
    hotplug_callback, 
    NULL, 
    hp 
    ); 

    if (LIBUSB_SUCCESS != rc) { 
    libusb_exit (context); 
    return rc; 
    } 

    while(1) { 
    rc = libusb_handle_events(context); 
    } 

    return 0; 
} 
그것이 출력 libusb_close

에 달려이 코드 그래서

int LIBUSB_CALL hotplug_callback(libusb_context *ctx, libusb_device *dev, libusb_hotplug_event event, void *user_data) 
{ 
    std::future<void> result(std::async([] (libusb_device *d) { 

    libusb_device_handle *h; 

    printf("%s\n", "Opening"); 
    int rc = libusb_open(d, &h); 
    if(rc != LIBUSB_SUCCESS) { 
     printf("ERROR: %s\n", libusb_error_name(rc)); 
     return; 
    } 
    printf("%s\n", "Opened"); 

    printf("%s\n", "Closing"); 
    libusb_close(h); 
    printf("%s\n", "Closed!"); 

    }, dev)); 

    result.get(); 

    return 0; 
} 

: 여기

내 핫 플러그 ​​콜백입니다

이 코드는 좀 더 프로토 타입이므로 실제로 작성한 것은 아닙니다. 아직 libusb의 탐색 모드에 있습니다.

답변

3

According to their own website, libusb (및 std::async은 직렬화되지 않은 경우 본질적으로 멀티 스레딩)을 사용하는 경우에는 몇 가지 고려 사항이 필요합니다.

는 예를 들어, 특히 주 :

libusb_close()는 폴 세트에서 파일 디스크립터를 제거한다. 여기서 발생할 수있는 모든 종류의 경쟁 조건이 있으므로이 시점에는 아무도 이벤트 처리를 수행하지 않는 것이 중요합니다. 코드에서

, 다른에서 하나 개의 스레드에서 libusb_close에 전화 및 libusb_handle_events 사이에 동기화가 없다. (위와 같은 소스에서) 관련 :

문제는 두 개 이상의 스레드가 동시에 libusb를의 파일 기술자에 대한 설문 조사() 또는 선택()를 호출하는 경우 만 스레드 중 하나가 때 일어났다됩니다 다음이다 이벤트가 도착합니다. 다른 사람들은 아무 일도 일어나지 않았다고 완전히 깨닫지 않을 것입니다.

여기에서 발생하는 메인 스레드에서 libusb_handle_events가 돌아 오지 않을 만들기, libusb_close이 기다리고 있음을 이벤트를 "훔치고"있다는 것을 전혀 상상할 수있다.

결론은 당신이 중 하나를 필요가있다 : 어떻게 멀티 스레딩과 libusb를 사용하는

  1. 상세 설명 링크 된 기사를 따르거나
  2. 는 libusb를 비동기 API를 이해하고 확인 대신 그 사용.
+0

감사합니다. 드디어 비동기 API를 사용했습니다. – pdiddy