使用C++11异步时Libusb挂起

使用C++11异步时Libusb挂起,c++,multithreading,c++11,libusb-1.0,C++,Multithreading,C++11,Libusb 1.0,我是libusb的新手,所以我不是很了解它。我正在做一些USB通讯 我使用的是热插拔功能,效果非常好。所以我想,当我检测到设备到达事件时,我会使用异步功能在另一个线程上与USB进行所有通信,这样我就可以对多个设备进行同步I/O,只需编写代码。他们的异步I/O让我有点困惑。希望我能使用C++ I/O异步同步特性。 但是我遇到了一个问题,当代码在C++11异步特性中运行时,一些libusb调用似乎挂起。当它不在C++11异步特性中运行时,它可以正常工作 所以我假设问题出在我的C++11异步特性代码上

我是libusb的新手,所以我不是很了解它。我正在做一些USB通讯

我使用的是热插拔功能,效果非常好。所以我想,当我检测到设备到达事件时,我会使用异步功能在另一个线程上与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;
}
主代码如下所示:

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的探索模式。

,对libusb和std::async使用多线程本质上是多线程的,如果它不是串行的,则需要考虑很多因素

例如,它们特别指出:

libusb_close将从轮询集中删除文件描述符。这里可能会出现各种各样的比赛情况,因此此时没有人进行事件处理是很重要的

在代码中,一个线程中对libusb_close的调用与另一个线程中的libusb_handle_事件之间没有同步。与上述来源相同:

问题是,如果两个或多个线程同时调用libusb的文件描述符上的poll或select,那么当事件到达时,这些线程中只有一个会被唤醒。其他人将完全忘记发生了什么事

完全可以想象,这里发生的是,主线程中的libusb_handle_事件正在窃取libusb_close等待的事件,使其永远不会返回

底线是您需要:

请阅读链接文章,该文章详细解释了如何将libusb与多线程结合使用,或者 理解libusb的异步API并利用它。
谢谢,我最终选择了他们的异步API
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;
}