本文主要探讨c++相关知识。
thread
多线程编程问题:线程间互斥通过互斥锁或CAS解决,线程间通信通过
类实例化的对象函数可作为线程函数
类成员函数可bind(绑定成员函数和this)做为线程函数
类成员函数需lambda捕获this指针,在lambda内调用成员函数
类成员函数可使用静态成员函数或友元函数调用成员函数
静态成员函数不能访问非静态成员变量或成员函数
类成员函数可外部外部普通函数传参调用成员函数
detach函数将子线程与主线程分离,主线程结束后分离的子线程自动结束(不安全)
lock_guard类似智能指针锁(auto_ptr),出{}释放资源,不支持赋值和重载
unique_lock类似智能指针锁(unique_ptr),拷贝和赋值为delete,可右值引用赋值
CAS保证+/-操作的原子特性
condition_variable类用于线程间的条件变量和线程同步
wait()线程进入等待状态,wait_for()可指定等待时间
notify_one()/notify_all()函数唤醒
单例模式
单例模式:类创建多次对象,只得到一个对象(日志,数据库),构造私有化,定义唯一static对象,对外接口返回唯一实例对象,删除拷贝和赋值函数
饿汉单例:未获取实例对象,实例对象已产生
懒汉单例:第一次获才产生对象(初始化)
demo1:
thread
文件结构
run.sh
#!/bin/bash
if [ -f ./Makefile ]
then
make clean
fi
cmake .
make
echo "---------------------------------"
./pro
CMakeLists.txt
CMAKE_MINIMUM_REQUIRED(VERSION 2.20) #最低版本要求
SET(CMAKE_CXX_COMPILER "g++-11") #设置g++编译器
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g") #添加编译选项
PROJECT(CLASS) #设置工程名
MESSAGE(STATUS "C++ test") #打印消息
ADD_EXECUTABLE(pro main.cpp) #生成可执行文件
clean.sh
#!/bin/bash
ls|grep -Ev "CMakeLists.txt|run.sh|clean.sh|main.cpp"|xargs -I {} trash-put {}
mian.cpp
#include <iostream>
#include <thread>
#include <functional>
class Thread_test;
void do_task(Thread_test &Thread_t);
class Thread_test
{
public:
void Task()
{
std::cout << "Thread_1 id : " << std::this_thread::get_id() << std::endl;
}
void StartTask1()
{
std::thread t1(std::bind(&Thread_test::Task,this));
t1.join();
}
void StartTask2()
{
std::thread t2([this]()
{
this->Task();
});
t2.join();
}
friend void do_task(Thread_test &Thread_t);
void StartTask3()
{
//ref传输引用给无法接受引用的参数(按引用传递)
//thread的构造中第一个为线程函数,其余均为线程参数
std::thread t3(do_task,std::ref(*this));
t3.join();
}
static void Do_task(Thread_test & tt)
{
tt.Task();
}
void StartTask4()
{
std::thread t4(Do_task,std::ref(*this));
t4.join();
}
};
void do_task(Thread_test &Thread_t)
{
Thread_t.Task();
}
int main()
{
Thread_test tt;
tt.StartTask1();
tt.StartTask2();
tt.StartTask3();
tt.StartTask4();
return 0;
}
结果示例:
demo2:
mutex,atomic
文件结构
run.sh
#!/bin/bash
if [ -f ./Makefile ]
then
make clean
fi
cmake .
make
echo "---------------------------------"
./pro
CMakeLists.txt
CMAKE_MINIMUM_REQUIRED(VERSION 2.20) #最低版本要求
SET(CMAKE_CXX_COMPILER "g++-11") #设置g++编译器
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g") #添加编译选项
PROJECT(CLASS) #设置工程名
MESSAGE(STATUS "C++ test") #打印消息
ADD_EXECUTABLE(pro main.cpp) #生成可执行文件
clean.sh
#!/bin/bash
ls|grep -Ev "CMakeLists.txt|run.sh|clean.sh|main.cpp"|xargs -I {} trash-put {}
mian.cpp
#include <iostream>
#include <thread>
#include <list>
#include <mutex>
#include <atomic>
std::mutex mtx;
std::atomic_uint num = 20;
void Task(int idx)
{
while(num > 0)
{
{
std::unique_lock<std::mutex> ul(mtx);
if(num > 0) //资源合法性校验
{
std::cout << idx << ":" << num << std::endl;
num--;
}
}
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
int main()
{
std::list<std::thread> tl;
for(int i = 0;i < 5;i++)
{
tl.push_back(std::thread(Task,i));
}
for(std::thread &t : tl)
t.join();
return 0;
}
结果示例:
demon3:
生产消费者模型
文件结构
run.sh
#!/bin/bash
if [ -f ./Makefile ]
then
make clean
fi
cmake .
make
echo "---------------------------------"
./pro
CMakeLists.txt
CMAKE_MINIMUM_REQUIRED(VERSION 2.20) #最低版本要求
SET(CMAKE_CXX_COMPILER "g++-11") #设置g++编译器
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g") #添加编译选项
PROJECT(CLASS) #设置工程名
MESSAGE(STATUS "C++ test") #打印消息
ADD_EXECUTABLE(pro main.cpp) #生成可执行文件
clean.sh
#!/bin/bash
ls|grep -Ev "CMakeLists.txt|run.sh|clean.sh|main.cpp"|xargs -I {} trash-put {}
mian.cpp
#include <iostream>
#include <thread>
#include <mutex>
#include <atomic>
#include <condition_variable>
std::mutex mtx;
std::condition_variable cv;
std::atomic_uint produce = 3;
std::atomic_uint value = 0;
void create_Task()
{
while(1)
{
std::unique_lock<std::mutex> ul(mtx);
if(produce > 0)
cv.wait(ul);
value = rand()%5;
produce += value;
std::cout << "create_Task:" << value << ",produce:" << produce << std::endl;
cv.notify_all();
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
void consumer_Task()
{
while(1)
{
std::unique_lock<std::mutex> ul(mtx);
while(produce == 0)
cv.wait(ul);
produce--;
std::cout << "consumer_Task:" << value << ",produce:" << produce << std::endl;
cv.notify_all();
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
int main()
{
std::thread t1(create_Task);
std::thread t2(consumer_Task);
t1.join();
t2.join();
return 0;
}
结果示例:
demo4:
单例模式
文件结构
run.sh
#!/bin/bash
if [ -f ./Makefile ]
then
make clean
fi
cmake .
make
echo "---------------------------------"
./pro
CMakeLists.txt
CMAKE_MINIMUM_REQUIRED(VERSION 2.20) #最低版本要求
SET(CMAKE_CXX_COMPILER "g++-11") #设置g++编译器
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g") #添加编译选项
PROJECT(CLASS) #设置工程名
MESSAGE(STATUS "C++ test") #打印消息
ADD_EXECUTABLE(pro main.cpp) #生成可执行文件
clean.sh
#!/bin/bash
ls|grep -Ev "CMakeLists.txt|run.sh|clean.sh|main.cpp"|xargs -I {} trash-put {}
mian.cpp
#include <iostream>
//饿汉单例
class Single_h
{
public:
static Single_h* get_single()
{
return & single_h;
}
private:
static Single_h single_h;
Single_h(){}
Single_h(const Single_h&) = delete;
Single_h& operator=(const Single_h&) = delete;
};
Single_h Single_h::single_h;
//懒汉单例
class Single_l
{
public:
static Single_l* get_single()
{
static Single_l single_l;
return &single_l;
}
private:
Single_l(){}
Single_l(const Single_l&) = delete;
Single_l& operator=(const Single_l&) = delete;
};
int main()
{
Single_h *s1 = Single_h::get_single();
Single_h *s2 = Single_h::get_single();
Single_h *s3 = Single_h::get_single();
Single_l *s4 = Single_l::get_single();
Single_l *s5 = Single_l::get_single();
Single_l *s6 = Single_l::get_single();
std::cout << "s1:" << s1 << std::endl;
std::cout << "s2:" << s2 << std::endl;
std::cout << "s3:" << s3 << std::endl;
std::cout << "s4:" << s4 << std::endl;
std::cout << "s5:" << s5 << std::endl;
std::cout << "s6:" << s6 << std::endl;
return 0;
}
结果示例: