qq_39658113 2024-06-28 15:33 采纳率: 0%
浏览 6

C++多线程访问对象世纪难题

情况是这样的,我需要与一个设备进行连接通讯。这个设备提供了dll供我调用,首先需要调用设备的连接函数connect(),连接函数里面会返回一个short类型的句柄,我在后续调用其他库函数的时候都需要传入这个句柄值。在单线程的情况下,一切都正常。但是在多线程的情况下,不同线程来调用库函数时,都需要重新调用连接函数获取新的句柄值才行。比如A线程最开始调用连接函数connect(),获得了句柄值30001,这时B线程需要调用获取状态函数GetStatus(),将A线程的句柄值30001传入GetStatus()中,但是返回调用失败,只有在B线程中重新调用connect(),获取新的句柄值30002才行。意思就是说创建出来的句柄值不能在其他线程共用。怎么才能解决这个问题,这个问题感觉跟com接口在多线程中使用的情况一样,调用了另一个线程创建的接口时会出错。但是com我可以用全局接口表的方式解决。这个short类型的句柄值该怎么解决。

  • 写回答

1条回答 默认 最新

  • 专家-赤兔[在线] 优质创作者: 编程框架技术领域 2024-06-28 15:33
    关注

    引自免费微信小程序:皆我百晓生

    你遇到的问题是一个多线程访问同一资源时的同步问题。在多线程环境下,多个线程同时访问共享资源,特别是涉及资源创建、销毁和状态改变的函数时,可能会引发竞争条件,导致资源状态不一致或数据错误。在你的场景中,设备的连接函数返回的句柄值似乎是为每个线程独立的,这意味着在多线程环境下需要为每个线程单独管理这些句柄。

    解决此问题的一种常见策略是使用线程局部存储(Thread Local Storage,TLS)或者线程安全的数据结构来存储每个线程的句柄值。这样,每个线程都有其自己的句柄副本,不会与其他线程冲突。以下是可能的解决方案:

    解决方案一:使用线程局部存储(TLS)

    你可以为每个线程分配一个线程局部变量来存储句柄值。这样,每个线程都有自己独立的句柄副本。这样你就不需要在不同的线程之间共享句柄了。例如:

    代码示例(使用C++11中的std::thread_local关键字):

    #include <thread>
    #include <atomic>
    
    // 假设你有一些全局函数来操作句柄和调用设备API
    extern "C" short connect_to_device(); // 连接设备函数,返回句柄值
    extern "C" int get_status_with_handle(short handle); // 使用句柄获取设备状态函数
    extern "C" void close_handle(short handle); // 关闭句柄的函数(可选)
    
    // 使用thread_local存储句柄的线程局部变量
    std::thread_local short handle = INVALID_HANDLE_VALUE; // 使用一个初始无效值表示未连接状态
    std::atomic<bool> is_connected = false; // 用于标记当前线程是否已经连接设备(可选)
    
    void thread_function() {
        if (!is_connected) { // 如果当前线程尚未连接设备,则进行连接操作
            handle = connect_to_device(); // 获取句柄值并存储到线程局部变量中
            is_connected = true; // 设置当前线程已连接状态标志位为true(可选)
        }
        // 现在你可以使用这个句柄安全地调用设备的其他函数了,不必重新连接设备
        int status = get_status_with_handle(handle); // 使用该线程的句柄值调用其他函数获取状态等操作
        // 其他使用设备的代码逻辑... 必要时进行设备断开操作 close_handle(handle); (可选)
    }
    

    在这个例子中,每个线程都有自己的handle变量副本,它们不会互相干扰。这样你就不需要在不同的线程之间共享句柄值了。此外,如果每次操作后关闭句柄或使用引用计数等技术来管理句柄的生命周期也是一个好策略。这可以防止句柄泄漏并减少不必要的资源浪费。请注意,这个例子中的代码是示意性的,实际实现可能需要根据你的具体需求和设备的API进行调整。此外,确保在每次创建新线程之前适当地初始化或重置线程局部变量也是很重要的。你可以考虑在全局的线程本地存储区中设置一个函数来管理这些句柄的创建和销毁过程。此外,在多线程环境下处理异常情况和确保资源的安全清理也是非常重要的部分。务必确保代码在多线程环境中是健壮和安全的。

    评论 编辑记录

报告相同问题?

问题事件

  • 创建了问题 6月28日