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);
}
原文地址:https://www.cnblogs.com/monicalee/p/3847532.html