首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用C++11异步时Libusb挂起

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

Stack Overflow用户
提问于 2016-10-04 20:20:44
回答 1查看 1.7K关注 0票数 2

我对libusb并不熟悉,所以我不太了解它。我想做一些USB通讯。

我正在使用热插拔功能,它运行得很好。所以我想,当我检测到一个设备到达事件时,我会使用C++11异步特性在另一个线程上与USB进行所有通信,这样我就可以与多个设备进行同步I/O,只需编写代码。他们的异步I/O让我有点困惑。希望我能够使用带有C++异步特性的同步I/O。

但是,当代码在C++11异步特性中运行时,某些libusb调用似乎挂起了,我遇到了一个问题。当它没有在C++11异步特性中运行时,它可以正常工作,没有任何问题。

所以我假设问题是我的C++11异步特性代码。

这是我的热插拔回拨:

代码语言:javascript
复制
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

它的产出如下:

代码语言:javascript
复制
Opening
Opened
Closing

主要代码如下所示:

代码语言:javascript
复制
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勘探模式。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-10-11 09:32:05

根据他们自己的网站,在libusb中使用多线程(如果没有序列化的话,std::async本质上就是多线程),需要考虑一些问题。

例如,它们明确指出:

libusb_close()将从轮询集中移除文件描述符。这里有各种各样的比赛条件,所以在这个时候没有人做事件处理是很重要的。

在您的代码中,对libusb_close的调用在一个线程中与在另一个线程中的libusb_handle_events调用之间没有同步。相关(来自上述同一来源):

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

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

底线是,您需要:

  1. 按照链接的文章,详细解释如何使用libusb与多线程,或
  2. 理解libusb的异步API并使用它。
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39861085

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档