【Linux课程学习】:锁封装(Mutex)线程封装(Thread),this指针

🎁个人主页:我们的五年****

🔍系列专栏:Linux课程学习****

🌷追光的人,终会万丈光芒

🎉欢迎大家点赞👍评论📝收藏⭐文章

Linux学习笔记:

https://blog.csdn.net/djdjiejsn/category_12669243.html

前言:

C++中已经封装了线程,在这里我们自己对线程进行封装,能更好的理解C++中的线程封装。我们自己封装的线程肯定比不了C++线程库中的封装,但是也能锻炼我们。

目录

下面关于锁的封装看看下面的:

1.访问内部私有成员变量

2.Thread成员变量:

[2.1.首先肯定是线程的tid:pthread_t _tid。](#2.1.首先肯定是线程的tid:pthread_t _tid。)

[2.2.进程的pid:pid_t _pid;。](#2.2.进程的pid:pid_t _pid;。)

2.3.线程的状态:

2.4.是否被分离:

2.5.线程名字

2.6.执行的方法:

3.内部成员方法:

3.1构造函数:

3.2Start函数:

3.3Stop函数:

4.整体代码:


下面关于锁的封装看看下面的:

Lockguard的构造函数加锁,析构函数解锁,用起来很方便。

cpp 复制代码
namespace MutexModule
{

    class Mutex
    {
    private:
        Mutex(const Mutex &) = delete;
        const Mutex &operator=(const Mutex &) = delete;

    public:
        Mutex()
        {
            int n = ::pthread_mutex_init(&_mutex, nullptr);
            (void)n;
        }
        void Lock()
        {
            int n = ::pthread_mutex_lock(&_mutex);
            (void)n;
        }
        void UnLock()
        {
            int n = ::pthread_mutex_unlock(&_mutex);
            (void)n;
        }
        pthread_mutex_t *LockPtr()
        {
            return &_mutex;
        }
        ~Mutex()
        {
            int n = ::pthread_mutex_destroy(&_mutex);
            (void)n;
        }

    private:
        pthread_mutex_t _mutex;
    };
    class LockGuard
    {
    public:
        LockGuard(Mutex &mtx) : _mtx(mtx)
        {
            _mtx.Lock();
        }
        ~LockGuard()
        {
            _mtx.UnLock();
        }
    private:
        Mutex &_mtx;
    };
}

1.访问内部私有成员变量

1.类中的static函数为什么不能直接访问内部成员变量?

因为默认没有传this指针。所以static函数参数中有this指针的时候,还是可以访问的,此时this(对象)指针不能省略。

2.外部函数不能访问私有成员?

没有默认传递this指针,没有访问权限。声明是类的友元函数的时候,也是可以访问的。

代码:

#include <iostream>
using namespace std;

class Solution {
public:
	Solution()
		:_n(1111)
	{
	
	}
	friend static void test(Solution* t);

	static void func()
	{
		
	}

	static void a()
	{
		//可以访问静态成员方法,访问权限给到了private
		// 就是没有默认传递this指针而已
		func();
		_m = 11;
	}
	static void b(Solution* t)
	{
		//可以访问静态成员方法,访问权限给到了private
		// 就是没有默认传递this指针而已
		t->_n = 555;
		t->_m;
		t->func();
	}

private:
	int _n;
	static int _m;
};

void test(Solution* t)
{
	//能访问是传递了Solution对象,是Solution类的友元
	//friend static void test(Solution*& t);
	t->_n = 222;
}

2.Thread成员变量:

2.1.首先肯定是线程的tid:pthread_t _tid。

2.2.进程的pid:pid_t _pid;。

pthread_t _tid;

pid_t _pid;

2.3.线程的状态:

enum class STATUS

{

RUNNING=1,

STOP,

NEW //新的线程的状态

};

STATUS _status;

表示线程的状态,NEW表示新的线程,还没有进行Start操作时的状态信息。

2.4.是否被分离:

线程默认是没有被分离的,而且只有分离和没有被分离两种情况,bool类型。

bool _joinable; //是否被分离

join命名就是,当joinable为true的时候,主线程要进行join,为false的时候,就不要进行join。

void EnableDetach()
{
    //状态变为false,新的线程默认为true
    _joinable=false;
}

void Detach()
{
    EnableDetach();
    //线程分离
    pthread_detach(_tid);
}

2.5.线程名字

为了区分不同的线程可以给线程取个名字。

std::string _name;

名字可以取"thread-num"表示是第几个线程。

2.6.执行的方法:

这里定义的是void(std::string name),返回值为void,参数是string的函数。

using func_t=std::function(void(std::string name));


3.内部成员方法:

3.1构造函数:

_name:

线程名字以"thread-num"来命名,表示第几个线程。所以定义一个static int num进行记录有多少个线程。但是这是临界资源,线程再创建线程,导致方式混乱。

static int num=1;

_joinable:

_joinable默认是没有被分离的,所以是true。

_func:

_func是外部传进来要执行的方法。所以要有func_t 参数。

_status:

为新线程,状态为NEW

_tid:

在线程创建的时候,传到pthread里面进行确定。

cpp 复制代码
Thread(func_t func)
       :_pid(getpid())
       ,_func(func)
       ,_joinable(true)
       ,_status(STATUS::NEW)
{
      LockGuard lockguard(_lock);
      {
       _name="thread-"+std::to_string(num++);  
      }
}

3.2Start函数:

先判断是不是没有在RUNNING,如果在RUNNING就返回false。然后创建线程进行执行,状态修改。

cpp 复制代码
static void* Routine(void* args)
{
     Thread* t=static_cast<Thread*>(args);
     t->_status=STATUS::RUNNING;
     t->_func(t->Name());
     return nullptr;
}

bool Start()
{
     if(_status!=STATUS::RUNNING)
     {
           int n=::pthread_create(&_tid,nullptr,Routine,this);
           if(n!=0)
           {
               //线程创建失败
               return false;
           }
           return true;
     }
     //已经在RUNNING了
     return false;
}

3.3Stop函数:

cpp 复制代码
bool Stop()
{
    //在运行的时候,才能cancle
    if(_status==STATUS::RUNNING)
    {
        _status=STATUS::STOP;
        int n=::pthread_cancel(_tid);
        if(n!=0)
        {
            return true;
        }
    }
    return true;
}

3.4Join函数,EnableJoin函数:

cpp 复制代码
void EnableDetach()
{
	//状态变为false
	_joinable = false;
}

bool Join()
{
	//没有被分离才能join
	if (_joinable)
	{
		int n = ::pthread_join(_tid, nullptr);
		if (n != 0)
			return false;
		_status = STATUS::STOP;
		return true;
	}
	return false;
}

void Detach()
{
	EnableDetach();
	//线程分离
	pthread_detach(_tid);
}

4.整体代码:

cpp 复制代码
#pragma once 

#include <iostream>
#include <cstdio>
#include <string.h>
#include <cstring>

#include <pthread.h>
#include <functional>
#include <unistd.h>
#include <sys/types.h>

#include "Mutex.hpp"

namespace ThreadModule
{
    using namespace MutexModule;
    using func_t=std::function<void(std::string name)>;
    static int num=1;

    enum class STATUS
    {
        RUNNING=1,
        STOP,
        NEW     //新的线程的状态
    };

    class Thread
    {
    private:
        //执行方法,routine惯例
        static void* Routine(void* args)
        {
            Thread* t=static_cast<Thread*>(args);
            t->_status=STATUS::RUNNING;
            t->_func(t->Name());
            return nullptr;
        }

        void EnableDetach()
        {
            //状态变为false
            _joinable=false;
        }

    public:
        Thread(func_t func)
            :_pid(getpid())
             ,_func(func)
             ,_joinable(true)
             ,_status(STATUS::NEW)
        {
            LockGuard lockguard(_lock);
            {
                _name="thread-"+std::to_string(num++);  
            }
        }

        bool Start()
        {
            if(_status!=STATUS::RUNNING)
            {
                int n=::pthread_create(&_tid,nullptr,Routine,this);
                if(n!=0)
                {
                    //线程创建失败
                    return false;
                }
                return true;
            }
            //已经在RUNNING了
            return false;
        }

        bool Stop()
        {
            //在运行的时候,才能cancle
            if(_status==STATUS::RUNNING)
            {
                _status=STATUS::STOP;
                int n=::pthread_cancel(_tid);
                if(n!=0)
                {
                    return false;
                }
                return true;
            }
            return true;
        }

        bool Join()
        {
            //没有被分离才能join
            if(_joinable)
            {
                int n=::pthread_join(_tid,nullptr);
                if(n!=0)
                    return false;
                _status=STATUS::STOP;
                return true;
            }
            return false;
        }
        
        void Detach()
        {
            EnableDetach();
            //线程分离
            pthread_detach(_tid);
        }

        std::string Name()  {return _name;}
        bool JoinAble(){return _joinable;}
        ~Thread()
        {
        }
    private:
        std::string _name;  //线程名字
        pthread_t _tid;     //线程tid
        pid_t _pid;         //线程属于哪个进程pid
        
        STATUS _status;     //线程的状态
        bool _joinable;     //是否被分离
        func_t _func;       //线程执行的方法

        Mutex _lock;        //锁进行保护
    };
}

|------------|
| Start |
| Stop |
| Join |
| EnableJoin |
| Name |
| JoinAble |

感谢阅读,相信美好的事情即将发生。

相关推荐
Joeysoda1 小时前
Java数据结构 (链表反转(LinkedList----Leetcode206))
java·linux·开发语言·数据结构·链表·1024程序员节
是阿建吖!1 小时前
【Linux】多线程(一)
linux·c语言·c++
YH_DevJourney1 小时前
Linux-C/C++--深入探究文件 I/O (下)(文件共享、原子操作与竞争冒险、系统调用、截断文件)
linux·c语言·c++
wangchen_01 小时前
算法中的移动窗帘——C++滑动窗口算法详解
开发语言·c++·算法
old_power1 小时前
【PCL】Segmentation 模块—— 欧几里得聚类提取(Euclidean Cluster Extraction)
c++·计算机视觉·3d
希望奇迹很安静2 小时前
[极客大挑战 2019]PHP
开发语言·学习·web安全·php·ctf·buuctf
zpsimon2 小时前
nsenter命令工具介绍与使用
linux
pystraf2 小时前
P9069 [Ynoi Easy Round 2022] 堕天作战 TEST_98 Solution
数据结构·c++·算法
涅槃寂雨2 小时前
C语言小任务——1000以内含有9的数字
c语言·开发语言·算法
ThisIsClark2 小时前
【gopher的java学习笔记】Java中Service与Mapper的关系详解
java·笔记·学习