2016-10-04 4 views
1

私はlibusbを使い慣れていないので、あまりよく分かりません。私はいくつかのUSB通信をしようとしています。C++ 11 asyncを使用しているときにLibusbがハングアップする

私は非常にうまく動作するホットプラグ機能を使用しています。だから、私はデバイスが到着イベントを検出したときに、私は別のスレッドでC++11非同期機能を使用してUSBとのすべての通信を行うだろうと思ったので、単純なコードに複数のデバイスで同期I/Oを行うことができます。彼らの非同期I/Oは私にとってはちょっと混乱します。うまくいけば、C++非同期機能で同期I/Oを使用することができます。

しかし、コードがC++ 11の非同期機能で動作しているときにlibusb呼び出しがハングアップするような問題があります。 C++ 11の非同期機能で動作していないときは問題なく動作します。

私はそれが私のC++ 11の非同期機能コードであると仮定しています。ここで

は私のホットプラグコールバックです:

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_close

でハングそれは出力:

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の探査モードです。

答えて

3

According to their own websiteで、libusbでマルチスレッドを使用しています(そして、シリアル化されていないと本質的にマルチスレッドです)。例えば

、彼らは、具体的な状態:

libusb_closeは()ポールセットからファイル記述子を削除します。ここではあらゆる種類の競合状態が発生する可能性があるため、現時点では誰もイベント処理を行っていないことが重要です。あなたのコードで

、1つのスレッドでlibusb_closeへの呼び出しやその他でlibusb_handle_events間の同期はありません。 (上記と同じソースから)関連:

問題が二つ以上のスレッドが同時にのlibusbのファイル記述子のポーリング()または選択()を呼び出している場合のみ、それらのスレッドのいずれかがアップしたときに起こされるその後、ということですイベントが到着します。他の人は何かが起こったことを完全に知らないでしょう。

は、どのようなここで起こることは、メインスレッドでlibusb_handle_eventsが、それは決して戻らない作り、libusb_closeが待っているというイベントを「盗む」されていることであることを完全に想像です。

一番下の行は、あなたがいずれかをする必要があることです。

  1. は、リンクされたマルチスレッドでlibusbを使用する方法を詳細に説明し、物品、または
  2. はのlibusbの非同期APIを理解し、作る従ってくださいその代わりにそれの使用。
+0

ありがとう、私はついに非同期API – pdiddy

関連する問題