线程安全: 如果多线程程序每次运行结果和单线程运行的结果一致,那么线程就是安全的
#include <thread>
void test(const string &msg)
{
std::cout << msg << std::endl;
}
int mian()
{
//创建线程
std::thread thread1(test, "hello");
bool isJoin = thread1.joinable();
if(isJoin)
{
thread1.join();//主线程在这里等待子线程结束
}
//thread1.detach();//子线程在后台执行
}
`std::thread`的`joinable()`函数返回`false`的情况有以下几种:
1. **默认构造的线程对象**:即没有关联任何线程执行函数。
2. **已经被移动的线程对象**:线程对象的所有权已经被转移给另一个线程对象。
3. **已经被`join`的线程**:线程已经调用过`join()`,此时线程已经执行完毕,并且资源已经被清理。
4. **已经被`detach`的线程**:线程已经调用过`detach()`,线程与线程对象分离,独立运行。
锁:
#include <thread>
#include <mutex>
int shared_data = 0;
std::mutex mtx;
std::timed_mutex mtx;
void func()
{
for(int i = 0; i < 10; i++)
{
//mtx.lock();第一种方法
//std::lock_guard<std::mutex> lg(mtx);第二种方法
//std::unique_lock<std::mutex> lg(mtx);第三种方法
shared_data++;
//mtx.unlock();第一种方法
//还有一种是timed_mutex,可以指定等待锁的时间
}
}
int main()
{
std::thread t1(func);
std::thread t2(func);
t1.join();
t2.join();
std::cout << shared_data << std::endl;
return 0;
}
生产消费者
#include <iostream>
#include <thread>
#include <mutex>
#include <string>
#include <condition_variable>
#include <queue>
std::queue<int> g_queue;
std::condition_variable g_cv;
std::mutex mtx;
void Producer() //生产者
{
for(int i = 0; i < 10;i++)
{
std::unique_lock<std::mutex> lock(mtx);
g_queue.push(i);
//通知消费者
g_cv.notify_one();
}
}
void Consumer()
{
while(1)
{
std::unique_lock<std::mutex> lock(mtx);
//bool isempty = g_queue.empty();
// g_cv.wait(lock, !isempty);
g_cv.wait(lock, ()[]{return !g_queue.empty()});
int vaule = g_queue.front();
g_queue.pop();
}
}
int main()
{
std::thread t1(Producer);
std::thread t1(Consumer);
t1.join();
t2.join();
return 0;
}
线程池
#include <iostream>
#include <thread>
#include <mutex>
#include <string>
#include <condition_variable>
#include <queue>
#include <vector>
class ThreadPool{
public:
ThreadPool(int numThreads):stop(false)
{
for(int i=0;i < numThreads; i++)
{
thread.emplace_back([this]{
while(1){
std::unique_lock<std::mutex> lock(mtx);
condition.wait(lock,[this]{return !task.empty() || stop});
if (stop && tasks.empty())
{
return;
}
std::function<void()> task(std::move(tasks.front()));
tasks.pop();
lock.unlock();
task();
}
})
}
}
~ThreadPool()
{
std::unique_lock<std::mutex> lock(mtx);
stop = true;
condition.notify_all();
for(auto& t : threads)
{
t.join();
}
}
template<class F,class... Args>
void enqueue(F &&f, Args&&... args)
{
std::function<void()> task =
std::bind(std::forward<F>(f), std::forward<Args>((args)...));
std::unique_lock<std::mutex> lock(mtx);
tasks.emplace(std::move(task));
condition.notify_one();
}
private:
std::vector<std::thread> threads;
std::queue<std::function<void()>> tasks;
std::mutex mtx;
std::condition_variable condition;
bool stop;
};