• Android NDK篇-C++之 线程、锁、条件变量与生产消费模型


    1.android ndk编程 c++线程

    在Android NDK编程中,默认支持pthread线程。线程使用的步骤:

    • 声明线程id pthread_t pthreadID
    • 创建子线程pthread_create
    • 定义子线程回调函数void * task(void *args)

    如果需要线程同步,需要调用pthread_join 函数

    2.android ndk编程 c++ 互斥锁

    互斥锁mutex 的使用步骤:

    • 声明互斥锁pthread_mutex_t mutex
    • 初始化互斥锁pthread_mutex_init(&mutex,0)
    • 加锁 pthread_mutex_lock(&mutex)
    • 解锁pthread_mutex_unlock(&mutex)
    • 使用完后需要释放锁pthread_mutex_destroy(&mutex)
    3.android ndk编程 条件变量cond

    条件变量cond的使用步骤

    • 声明条件变量pthread_cond_t cond;
    • 初始化条件变量pthread_cond_init(&cond,0)
    • 线程阻塞等待pthread_cond_wait(&cond,&mutex)
    • 通知消费线程pthread_cond_signal(&cond) 如果是需要通知多个消费线程pthread_cond_broadcast(&cond)
    4.生产消费模型
    4.1c++ 定义线程安全队列
    #include 
    #include 
    #include 
    
    using namespace std;
    
    template
    
    class SafeQueue {
    private:
        queue queue;         //消息队列
        pthread_mutex_t mutex;  //互斥锁
        pthread_cond_t cond;   //定义条件变量
    public:
        SafeQueue(){
            pthread_mutex_init(&mutex, nullptr);
    
            pthread_cond_init(&cond, nullptr);
    
        }
    
        ~SafeQueue(){
            pthread_mutex_destroy(&mutex);
            pthread_cond_destroy(&cond);
        }
    
        void add(T t){
            //加锁
            pthread_mutex_lock(&mutex);
            queue.push(t);  //将数据加入队列
    
    //        pthread_cond_signal(&cond);  通知给单个线程进行消费
            //通知消费者
            pthread_cond_broadcast(&cond);
            cout << "add queue.push 我已经notifyAll所有等待线程了" << endl;
    
            pthread_mutex_unlock(&mutex);
    
        }
    
        void get(T &t){
    //        加锁
        pthread_mutex_lock(&mutex);
    
        while (queue.empty()){
            cout << "get empty 等待中.." << endl;
            pthread_cond_wait(&cond,&mutex);   //通过条件变量 进行线程等待
        }
    
        t=queue.front();// 得到 队列中的元素数据 仅此而已
        queue.pop(); // 删除元素
    
        pthread_mutex_unlock(&mutex);
    
        }
    
    };
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    4.2 生产者
    void * createMessage(void *args){
        for (int i = 100; i < 110; ++i) {
            sleep(1);
            __android_log_print(android_LogPriority::ANDROID_LOG_DEBUG,"lpf","生产数据 =%d",i);
            sq.add(i);
        }
        int value= *reinterpret_cast(args);
        __android_log_print(android_LogPriority::ANDROID_LOG_DEBUG,"lpf","生产数据 =%d 要停止消息循环",value);
    //    你只要传入 -1 就结束当前循环
        if (value==-1){
            sleep(10);
            sq.add(value); // 为了让消费者 可以结束循环
        }
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    4.3 消费者
    void * consume(void * args){
        while (true){
            int value;
            sq.get(value);
            __android_log_print(android_LogPriority::ANDROID_LOG_DEBUG,"lpf","消费数据:%d",value);
            if (-1==value){
                __android_log_print(android_LogPriority::ANDROID_LOG_DEBUG,"lpf","消费数据收到停止消费指令");
                break;
            }
        }
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    4.4 声明线程 启动生产者和消费者
    //定义消费者线程
    pthread_t pthreadConsume;
    pthread_create(&pthreadConsume,0,consume,0);
    
    //定义生成者线程
    int value=-1;
    pthread_t pthreadCreateMessage;
    pthread_create(&pthreadSet1,0,pthreadCreateMessage,&value);
    
    pthread_join(pthreadConsume, 0);
    pthread_join(pthreadCreateMessage, 0);
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
  • 相关阅读:
    门口通畅家运顺
    机器学习自学成才的十条戒律
    内卷室友系列 -- day01 计算机网络概论
    【黑马程序员JVM学习笔记】04.类加载与字节码技术
    51单片机STC89C52RC——5.1 LCD1602液晶显示屏
    Python从入门到精通— 初识Python
    InVideo AI:用人工智能轻松制作视频
    网页游戏的开发框架
    多策略改进哈里斯鹰优化算法-附代码
    Spring多数据源配置
  • 原文地址:https://blog.csdn.net/u014078003/article/details/126445069