线程类
线程类,需要标准库的thread,以及线程锁mutex
thread
#include <iostream>
#include <thread>
class my_thread{
public:
typedef void* Thread; //定义多线程指针
//创建多线程
//参数:
/*Thread: 多线程指针名称
* void(*)(void* arg): 线程启动的函数指针
* arg: 线程启动的函数指针所需要的输入参数
* */
template <typename T>
void createThread(Thread& thread, void (T::* func_thread)(void* arg), T* self, void* arg) {
if (thread == NULL)
{
std::thread* temp = new std::thread(func_thread, self, arg);
thread = (Thread)temp;
((std::thread*)thread)->detach();//线程分离,线程退出后系统自动回收资源
}
}
void destoryThread(Thread thread) {
if (thread != NULL) {
delete (std::thread*)thread;
}
}
void deleteThread(Thread thread) {
if (thread != NULL) {
delete (std::thread*)thread;
}
}
};
一些说明:
一、
void (T::* func_thread)(void* arg)
,函数指针func_thread
。函数是T
类的成员函数,返回值是void
,参数是一个void*
类型的参数。
二、
因为类的成员函数都还有一个隐藏指针this
,所以在构造thread是需要传递进去,即T* self
三、
在使用该类Thread类型定义多线程指针时,需要加上类名限定,例如:
my_thread::Thread thread_id_;
mutex
#include <mutex>
#include <iostream>
class my_mutex{
public:
typedef void* Mutex; //定义锁指针
void createMutex(Mutex& m)
{
if (m == NULL)
{
std::mutex* temp = new std::mutex();
m = (Mutex)temp;
}
}
void lock(Mutex m)
{
if (m != NULL)
((std::mutex*)m)->lock();
else
{
// cerr无需缓冲,比cout快
std::cerr << "error,the mutex is NULL!" << std::endl;
}
}
void unlock(Mutex m)
{
if (m != NULL)
((std::mutex*)m)->unlock();
else
std::cerr << "error,the mutex is NULL!" << std::endl;
}
void deleteMutex(Mutex m)
{
if (m != NULL)
delete ((std::mutex*)m);
}
};
my_thread.h
两个类合并起来
#ifndef MY_THREAD_H_
#define MY_THREAD_H_
#include <iostream>
#include <thread>
#include <mutex>
class my_thread
{
public:
typedef void* Mutex; //定义锁指针
void createMutex(Mutex& m)
{
if (m == NULL)
{
std::mutex* temp = new std::mutex();
m = (Mutex)temp;
}
}
void lock(Mutex m)
{
if (m != NULL)
((std::mutex*)m)->lock();
else
{
std::cerr << "error,the mutex is NULL!" << std::endl;
}
}
void unlock(Mutex m)
{
if (m != NULL)
((std::mutex*)m)->unlock();
else
std::cerr << "error,the mutex is NULL!" << std::endl;
}
void deleteMutex(Mutex m)
{
if (m != NULL)
delete ((std::mutex*)m);
}
typedef void* Thread; //定义多线程指针
//创建多线程
//参数:
/*Thread: 多线程指针名称
* void(*)(void* arg): 线程启动的函数指针
* arg: 线程启动的函数指针所需要的输入参数
* */
template <typename T>
void createThread(Thread& thread, void (T::* func_thread)(void* arg), T* self, void* arg) {
if (thread == NULL)
{
std::thread* temp = new std::thread(func_thread, self, arg);
thread = (Thread)temp;
((std::thread*)thread)->detach();//线程分离,线程退出后系统自动回收资源
}
}
void destoryThread(Thread thread) {
if (thread != NULL) {
delete (std::thread*)thread;
}
}
void deleteThread(Thread thread) {
if (thread != NULL) {
delete (std::thread*)thread;
}
}
};
#endif /* MY_THREAD_H_ */
typedef
这里再说一下 typedef
吧
用途一:定义一种类型的别名,而不只是简单的宏
// 看意思是想定义两个 char 型指针
// 但这里只有 pa 是指针,而 pb 是 char 型变量
char* pa,pb;
// 所以这里 * 的摆放位置可以变一下 char *pa, pb; 可能会让人注意到 pb不是指针
// 这里用typedef定义一个char * 类型的别名
typedef char* chptr;
chptr pa,pb; // pa 和 pb 都是char 型指针
用途二:在C语言代码中,定义结构体类型的别名
在C中,定义结构体变量,是需要加上关键字struct
,然后才是结构体 + 对象名。
而在C++中,是不需要关键字struct
的。
struct stct{
int a;
char b;
};
// C
struct stct test1;
// C++
stct test2;
// 那编写C语言代码时,可以在定义结构体时,加上typedef,声明一个结构体别名
typedef struct stct{
int a;
char c;
}STCT;
STCT test3; // 等同于 struct stct test3;
用途三:项目中,使用typedef声明一些“组合”类型的别名,在修改或移植到其他平台会更加方便快捷
// 声明 long double 类型为 READ
typedef long double READ;
// 但有些平台不支持 long
typedef double READ;
// 还有些平台不支持 double
typedef float READ;
用途四:为一些复杂的变量声明一个简单的别名
// 原声明
void (*b[10]) (void (*)());
// 这里这么看,b[10] 数组,每一个元素都是一个函数指针,类型是void (*)(ptr_func_param);
// ptr_func_param是 b[10] 这函数指针,函数的参数
// 而参数也是一个函数指针,类型是void(*)(),函数返回值类型是void,无参
// 所以第一步先声明 b[10]函数指针的参数 ptr_func_param
typedef void (*ptr_func_param)();
// 第二步就是声明 b[10] 的类型了 ptr_
typedef void (*ptr_)(ptr_func_param) ;
// 定义数组
ptr_ b[10];
前面定义了my_thread.h
类,在声明了Thread
和Mutex
两种类型。
声明的“位置”不同,使用的时候也不同
// 如果在类my_thread内的public权限下声明,在类外定义Thread变量
my_thread::Thread thread_;
// 如果是在private权限下声明,在类外不可以直接定义Thread变量
// 如果是在头文件my_thread.h中,但不在类my_thread中声明,那在类外定义Thread变量
Thread thread_; // 如果加上类my_thread限定反而出错