创建并启动多个线程
#include <iostream>
#include <thread>
void threadFunction(int id)
{
std::cout << "Hello from thread " << id << std::endl;
}
int main()
{
const int numThreads = 5;
std::thread threads[numThreads];
// 创建并启动多个线程
for (int i = 0; i < numThreads; ++i)
{
threads[i] = std::thread(threadFunction, i);
}
// 等待每个线程执行完毕
for (int i = 0; i < numThreads; ++i)
{
threads[i].join();
}
std::cout << "All threads joined!" << std::endl;
return 0;
}
线程间数据共享与同步
#include <iostream>
#include <thread>
#include <vector>
#include <mutex>
std::mutex mtx;
std::vector<int> sharedData;
void threadFunction(int id)
{
// 模拟向共享数据结构中添加数据
for (int i = 0; i < 5; ++i)
{
std::lock_guard<std::mutex> lock(mtx); // 使用互斥锁保护共享数据
sharedData.push_back(i);
std::cout << "Thread " << id << " added: " << i << std::endl;
}
}
int main() {
const int numThreads = 3;
std::thread threads[numThreads];
// 创建并启动多个线程
for (int i = 0; i < numThreads; ++i)
{
threads[i] = std::thread(threadFunction, i);
}
// 等待每个线程执行完毕
for (int i = 0; i < numThreads; ++i)
{
threads[i].join(); // 停等 等待线程完成
//threads[i].detach(); // 将线程后台运行,并且线程中的打印不会显示
}
如果是 detach 在这里 等待2秒以确保所有线程都已完成
// std::this_thread::sleep_for(std::chrono::seconds(2));
// 输出共享数据内容
std::cout << "Shared data contents:" << std::endl;
for (const auto& data : sharedData)
{
std::cout << data << " ";
}
std::cout << std::endl;
return 0;
}
thread
C++11提供了语言层面上的多线程,包含在头文件#include <thread>
中。它解决了跨平台的问题,提供了管理线程、保护共享数据、线程间同步操作、原子操作等类
简单例子
#include <thread> //多线程
#include <chrono> // 操作时间
void thread_1(std::string out)
{
for (int i = 0; i < 10; i++)
{
cout << out << endl;
std::this_thread::sleep_for(std::chrono::seconds(1)); // 秒
}
}
int main()
{
std::string out1 = "线程1##########################";
std::string out2 = "线程2**************************";
thread first(thread_1,out1);
thread second(thread_1, out2);
//必须说明添加线程的方式
// detach():异步的方式
// join():停等的方式
first.detach();
second.join();
std::cout << "子线程结束./n";//必须join完成
return 0;
}
结果:
线程2**************************线程1##########################
线程2**************************线程1##########################
线程2**************************
线程1##########################
线程1##########################
线程2**************************
线程1##########################
线程2**************************
线程1##########################
线程2**************************
线程2**************************线程1##########################
线程1##########################
线程2**************************
线程2**************************
线程1##########################
线程1##########################
线程2**************************
子线程结束./n
获取线程 ID
std::this_thread::get_id()
是C++中用于获取当前线程ID的方法。它属于#include <thread>
头文件中的 std 命名空间。- 获取线程ID是在线程函数中获取,再一次执行中线程的ID值不会变化,但再次运行ID值会变化
// C++多线程
#include <thread> //多线程
#include <chrono> // 操作时间
void thread_1(std::string out)
{
for (int i = 0; i < 10; i++)
{
std::thread::id thread_id = std::this_thread::get_id(); // 获取线程ID值
std::cout << "Thread ID: " << thread_id << std::endl; // 打印ID值
cout << out << endl;
std::this_thread::sleep_for(std::chrono::seconds(1)); // 秒
}
}
int main()
{
std::string out1 = "线程1##########################";
std::string out2 = "线程2**************************";
std::thread first(thread_1,out1);
std::thread second(thread_1, out2);
first.detach();
second.join();
std::cout << "子线程结束./n";//必须join完成
return 0;
}
结果:
线程2**************************
Thread ID: 1964
线程1##########################
Thread ID: 18540
线程2**************************
Thread ID: 1964
线程1##########################
Thread ID: 18540
线程2**************************
互斥锁
std::mutex
是C++中的互斥量(mutex)类,用于创建互斥锁,实现对共享资源的互斥访问保护。它属于 头文件中的 std 命名空间。
#include <thread>
#include <mutex>
std::mutex mtx; // 创建一个互斥量对象
int shared_variable = 0; // 共享资源
void task()
{
// 上锁
mtx.lock();
// 修改共享资源
shared_variable += 1;
// 打印共享资源的值
std::cout << "Current value: " << shared_variable << std::endl;
// 解锁
mtx.unlock();
}
int main() {
std::thread thread1(task);
std::thread thread2(task);
thread1.join();
thread2.join();
return 0;
}
- mtx.lock()将互斥锁上锁,此时其他线程如果试图获取锁则会被阻塞。
- 永远不要忘记调用mtx.unlock()来释放互斥锁,否则会导致死锁问题。
- 最好将互斥锁的上锁和解锁操作放在一个try/catch块中,以确保即使出现异常,互斥锁也能被正确释放。
- 尽量减小互斥锁的范围,只在需要保护共享资源的临界区内上锁。避免在锁外执行耗时操作,以充分发挥多线程并发性能。
- 如果有多个互斥锁,确保按照相同的顺序对它们进行上锁,以避免死锁的可能。
放弃执行
std::this_thread::yield()
函数的作用是提示线程调度器将当前线程放弃执行,以便让其他就绪态的线程有机会被调度执行。换句话说,它是一种线程主动让出CPU执行的方式。