首页 > 编程语言 >C++ 跨线程 传递指针

C++ 跨线程 传递指针

时间:2024-05-29 17:35:43浏览次数:27  
标签:std C++ dataQueue 线程 include ptr 指针

目录

    在C++中跨线程传递指针时,需要注意线程安全和生命周期管理的问题。以下是一些常见的方法,用于在C++中安全地跨线程传递指针:

    1. 使用智能指针和线程安全队列

    结合使用std::shared_ptr和线程安全的队列(如std::queue配合互斥锁)是一种常见的方法。

    #include <iostream>
    #include <thread>
    #include <queue>
    #include <mutex>
    #include <memory>
    
    std::queue<std::shared_ptr<int>> dataQueue;
    std::mutex mtx;
    
    void producerThread() {
        for (int i = 0; i < 10; ++i) {
            std::lock_guard<std::mutex> lock(mtx);
            dataQueue.push(std::make_shared<int>(i));
        }
    }
    
    void consumerThread() {
        while (true) {
            std::shared_ptr<int> data;
            {
                std::lock_guard<std::mutex> lock(mtx);
                if (!dataQueue.empty()) {
                    data = dataQueue.front();
                    dataQueue.pop();
                }
            }
            if (data) {
                std::cout << "Consumed: " << *data << std::endl;
            } else {
                // 队列为空,可以选择退出或继续等待
                break;
            }
        }
    }
    
    int main() {
        std::thread producer(producerThread);
        std::thread consumer(consumerThread);
        
        producer.join();
        consumer.join();
        
        return 0;
    }
    

    在这个例子中,producerThread生产数据并将其放入线程安全的队列中,而consumerThread从队列中消费数据。std::shared_ptr确保数据在最后一个引用它的线程释放之前不会被删除。



    1. 使用原子指针

    对于简单的指针传递,如果指针本身不会改变(即不会重新指向其他对象),可以使用std::atomic<T*>来确保跨线程操作的原子性。

    #include <iostream>
    #include <thread>
    #include <atomic>
    
    std::atomic<int*> atomicPtr(nullptr);
    
    void producerThread() {
        int value = 42;
        atomicPtr.store(&value); // 存储指针
    }
    
    void consumerThread() {
        int* ptr = atomicPtr.load(); // 加载指针
        if (ptr) {
            std::cout << "Consumed: " << *ptr << std::endl;
        }
    }
    
    int main() {
        std::thread producer(producerThread);
        std::thread consumer(consumerThread);
        
        producer.join();
        consumer.join();
        
        return 0;
    }
    

    注意,这里value的生命周期必须确保在消费者线程访问它之前不会结束。在实际应用中,通常会将数据封装在动态分配的对象中,并使用智能指针管理其生命周期。



    1. 使用消息传递库

    对于更复杂的并发场景,可以考虑使用消息传递库,如Boost.Interprocess、ZeroMQ或者其他第三方库。这些库提供了更高级的抽象和工具来处理线程间的通信和同步。

    注意事项:
    确保指针所指向的对象在传递过程中不会被意外删除或修改。
    如果指针所指向的对象本身不是线程安全的,那么必须确保对它的访问是同步的。
    避免在多个线程中删除同一个对象,这通常会导致未定义行为。
    测试和验证跨线程指针传递的代码,以确保没有内存泄漏、悬挂指针或其他并发问题。

    总之,跨线程传递指针需要谨慎处理,以确保数据的正确性和线程的安全性。使用智能指针、原子操作和线程安全的队列是常见的解决方案。

    标签:std,C++,dataQueue,线程,include,ptr,指针
    From: https://www.cnblogs.com/yubo-guan/p/18220736

    相关文章

    • C++:虚表指针、虚表、虚函数和动态多态
      classBase{public:virtualvoidshow(){std::cout<<"Baseshow"<<std::endl;}};classDerived_1:publicBase{public:voidshow()override{std::cout<<"Derivedshow"<<std::endl;}};class......
    • C++ 线程同步condition_variable的使用
      一,condition_variable使用步骤创建一个scondition_variable对象。创建一个互斥量对象mutex。创建两个线程:等待线程和唤醒线程。在等待线程中,使用unique_lock锁定互斥量,并调用wait函数进入等待状态。在唤醒线程lock_guard锁定互斥量,并调用notify_one或notify_all函数唤醒等......
    • C++ std::function和std::bind的六种用法总结
      一,使用funciton和bind的六种方法1,使用function接收普通函数2,使用function接收lambda函数3,使用function函数来接收函数对象4,使用bind函数绑定类中的一般函数5,使用bind函数绑定类中的多态函数6,使用function来实现回调。二,代码实现直接看代码和注释:#include<iostream>#......
    • C++语言实现身份证实名认证、身份证上的文字识别接口
      实名认证是什么意思呢?一般指的是对用户资料真实性进行的验证审核,这样有利于建立完善且可靠的互联网环境。如果交易双方使用的都是虚假信息,那么在诸多环节会存在很大的风险。另外,还有游戏平台对玩家进行实名认证,防止未成年人注册。翔云身份证实名认证接口,通过核验身份证二......
    • C++语言实现发票查验功能、医疗票据查验、财政票据识别
      封账结算是个苦活、累活,在账务干过的人都知道,就连发票都要一张一张的录,一张一张的审,结一次账、扒一层皮,就累得人仰马翻。除此之外,在临近春节的这个时期,账务部门的小伙伴们,只能眼巴巴地看着别人抢票,在财务报告初稿没有正式提交给审计师前,没人敢提前预定回家的票,甚至都不确定是......
    • Ubuntu下的onnxruntime(c++)编译 转载文章 非原创
      仓库下载gitclone--depth=1--branchv1.12.1https://github.com.cnpmjs.org/microsoft/onnxruntime.git注意:需要更换国内镜像源编译GPU./build.sh--skip_tests--use_cuda--configRelease--build_shared_lib--parallel--cuda_home/usr/local/cuda-11.3--cudnn_home/u......
    • C++中以类的成员函数作为Windows callback函数需要设置成static函数
      在看代码时,发现很多CALLBACK函数,所以仔细研究了一下C++中的CALLBACK函数首先,我们来理解一下,什么是C++中的CALLBACK函数 =>凡是由你设计,但是由Windows操作系统调用的函数,我们把它统称为CALLBACK函数,这些函数都有一定的类型,以方便配合Windows的调用动作某些WindowsAPI函数会要......
    • c++ 构造函数
       =================1.简介子类为完成基类初始化,在C++11之前,需要在初始化列表调用基类的构造函数,从而完成构造函数的传递。如果基类拥有多个构造函数,那么子类也需要实现多个与基类构造函数对应的构造函数。classBase{public: Base(intv):_value(v),_c(‘0’){} Base(cha......
    • 线程练习题
      编写一个程序,主线程中创建一个子线程,容纳后让主线程先退出并返回一个值,子线程接合主线程后输出主线程的退出值,然后子线程退出./********************************************************************* filename:pthread.c* author :Dazz* date :2024/05/29*......
    • QT C++实现表头添加组件
      QTableWidget在表头添加组件QTableWidget的表头有一个类QHeaderView是专门处理表头的类,要在表头添加一个类似QCheckBox的组件需要重写一个类并继承QHeaderView。QTableWidget中添加复选框并实现全选居中:自定义类MyHeaderView并继承QHeaderView自定义类MyTableWidget并继承QTa......