zoukankan      html  css  js  c++  java
  • 0714-----C++Primer听课笔记----------封装mutex,thread,condition等

    1.封装Mutex

    1.1 封装前先总结一下常用的mutex操作有:

    pthread_mutex_init(&mutex, NULL ); //初始化一个互斥锁

    pthread_mutex_destroy(&mutex); //销毁一个互斥锁

    pthread_mutex_lock(&mutex); //上锁

    pthread_mutex_unlock(&mutex);// 解锁

    1.2 用类把这下常用函数进行封装,代码如下,注意编译时不要忘记链接pthread。

    #ifndef __MUTEXLOCK_H__
    #define __MUTEXLOCK_H__
    
    #include <pthread.h>
    #include <stdexcept>
    
    class Mutexlock{
        public:
            Mutexlock(){
                if(pthread_mutex_init(&mutex_, NULL)){
                    throw std::runtime_error("init mutexlock error");
                }
            }
    
            ~Mutexlock(){
                if(pthread_mutex_destroy(&mutex_)){
                    throw std::runtime_error("destroy mutexlock error");
                }
            }
    
            void lock(){
                if(pthread_mutex_lock(&mutex_)){
                    throw std::runtime_error("lock muexlock errror");
                }
            }
    
            void unlock(){
                if(pthread_mutex_unlock(&mutex_)){
                   throw std::runtime_error("unlock mutexlock error");
                }
            }
    
        private:
            pthread_mutex_t  mutex_;
    };
    
    
    #endif

    2. 封装thread

    2.1 thread线程要用的:函数有:

    pthread_create(&tid, NULL, pthfunc,NULL);//创建一个线程

    pthread_join(&tid);   //回收一个线程的资源

    pthread_detach(tid);   //是系统自动回收线程资源

    2.2 类的普通成员函数的函数指针包含类名。例如 void* (Thread::)(void*)。

    #ifndef __THREAD_H__
    #define __THREAD_H__
    
    #include <pthread.h>
    
    class Thread{
        public:
            Thread();
            ~Thread();
    
            void start();
            static void *thread_func(void *arg);
            void run();
    
        private:
            pthread_t tid_;
            int a_;
    };
    
    
    
    #endif
    #include "thread.h"
    #include <iostream>
    
    using namespace std;
    
    Thread::Thread()
        :tid_(-1){
    }
    
    Thread::~Thread(){
        pthread_join(tid_, NULL);
    }
    
    void Thread::start(){
        pthread_create(&tid_, NULL, thread_func, this);
    }
    
    void *Thread::thread_func(void *arg){
        Thread *pt = static_cast<Thread *>(arg);
        pt->run();
    }
    
    void Thread::run(){
        cout << "my run " << endl;
        a_ = 10;
        cout << "a_ = " << a_ << endl;
    }

    2.3 Thread的封装问题:

    a) 函数指针问题,解决方案是使用static方法。

    b) 上述方案的缺点是线程中无法访问对象的私有数据。

    c) 解决方案是把对象的this指针当做线程参数传入。

    3.封装条件变量

    3.1条件变量常用的函数有

    pthread_cond_init(&empty); //初始化一个条件变量

    pthread_cond_wait(&empty, &mutex); //等待某个条件

    pthread_cond_signal(&empty);//唤醒一个等待该条件的线程

    pthread_cond_broadcast(&empty);//唤醒所有等待该条件的线程

    3.2代码

    #ifndef __CONDITION_H__
    #define __CONDITION_H__
    
    #include <pthread.h>
    
    class Mutexlock; //使用类的引用 因此采用前向声明即可
    
    class Condition{
        public:
            Condition(Mutexlock &lock);
            ~Condition();
    
            void wait();
            void notify();
            void notifyAll();
    
        private:
            pthread_cond_t  cond_;
            Mutexlock &lock_;
    
    };
    
    #endif
    #include "condition.h"
    #include <stdexcept>
    #include "mutexlock.h" //这里调用了mutexlock中的getMutexptr()函数 因此要加头文件
    
    Condition::Condition(Mutexlock &lock)
        :lock_(lock)
    {
        if(pthread_cond_init(&cond_, NULL) != 0){
            throw std::runtime_error("init failed");
        }
    }
    
    
    Condition::~Condition(){
        if(pthread_cond_destroy(&cond_) != 0){
            throw std::runtime_error("destroy failed");
        }
    }
    
    void Condition::wait(){
        if(pthread_cond_wait(&cond_, lock_.getMutexptr()) != 0){
            throw std::runtime_error("wait failed");
        }
    }
    
    void Condition::notify(){
        if(pthread_cond_signal(&cond_) != 0){
           throw std::runtime_error("signal failed");
        }
    }
    
    void Condition::notifyAll(){
        if(pthread_cond_broadcast(&cond_) != 0){
            throw std::runtime_error("broadcast failed");
        }
    }

    4 另一种封装线程的方法 (线程回调函数)

    4.1 直接将要调用的函数指针传入去初始化一个线程。这样可以避免频繁修改线程的执行函数。

    4.2 这个线程类目前只可以接收C函数,如果是一个C++成员函数,那么他的指针是 void *(Test::*) (void*)
    后面使用一种工具bind,可以实现函数的转化 boost::bind

    #ifndef __THREAD_H_
    #define __THREAD_H__
    
    #include <pthread.h>
    
    class Thread{
        public:
            typedef void* (*ThreadCallback)(void*); //定义一个函数指针类型
            Thread(ThreadCallback callback_);
            void start();
            void join();
        private:
            ThreadCallback  callback_;
            pthread_t tid_;
    };
    
    
    
    
    #endif
    #include <iostream>
    #include "thread.h"
    using namespace std;
    
    void * func(void * arg){
        cout << " callback OK " << endl;
        return NULL;
    }
    
    int main(int argc, const char *argv[])
    {
        Thread th(func);
        th.start();
        th.join();
        return 0;
    }
    #include "thread.h"
    
    Thread::Thread(ThreadCallback callback)
        :callback_(callback),tid_(0)
    {
    }
    
    void Thread::start(){
        pthread_create(&tid_, NULL, callback_, NULL);
    }
    
    void Thread::join(){
        pthread_join(tid_, NULL);
    }
  • 相关阅读:
    每日一篇文献:Robotic pick-and-place of novel objects in clutter with multi-affordance grasping and cross-domain image matching
    每日一篇文献:Intuitive Bare-Hand Teleoperation of a Robotic Manipulator Using Virtual Reality and Leap Motion
    每日一篇文献:Virtual Kinesthetic Teaching for Bimanual Telemanipulation
    HEBI Robotic Arm VR Teleoperation
    「iQuotient Case」AR device teleoperated robotic arm
    VR and Digital Twin Based Teleoperation of Robotic Arm
    HEBI Robotic Arm VR Teleoperation
    Human Robot Interaction
    Immersive Teleoperation Project
    机器人演示学习
  • 原文地址:https://www.cnblogs.com/monicalee/p/3847532.html
Copyright © 2011-2022 走看看