多线程(C++/Python)
本文包括一下内容:
通过C++11的标准库进行多线程编程,包括线程的创建/退出,线程管理,线程之间的通信和资源管理,以及最常见的互斥锁,另外对python下多线程的实现进行讨论。
[TOC]
- 前言
- 线程管理初步
- 1. 线程函数
- 2. 线程启动
- 3. 线程结束/退出
- 4. 线程传参
- 5. 互斥锁
- Python中的多线程
- 1. 线程中的参数访问ThreadLocal
- 2. Python中的锁机制Threading.Lock()
前言
多线程模型共享同一进程资源,通过多线程可以极大的提高代码的效率,完成单一线程无法完成的任务。
几个需要记住的点: C++中的线程是一个类
,因此可以像操作类一样进行操作; C++中的线程也是一类资源
;
sample
#include <iostream>
#include <thread>
void Thread_1() {
std::cout << "This is Thread_1." << std::endl;
return;
}
int main() {
std::thread t{
greeting}; // 列表初始化
t.join();
return 0;
}
以上是多线程下的HelloWorld!
,从上我们可以看出C++多线程编程的基本步骤:
创建线程函数 -> 实例一个线程 -> 运行
两个注意点
1. 编译 我们使用了C++11的特性以及线程库pthread,因此在编译的时候这两个都要说明:
g++ --std=c++11 -pthread main.cpp
2.线程初始化 从 C++ 11 开始,推荐使用列表初始化{}
的方式,构造类类型的变量。
线程管理初步
包括线程函数,启动线程,结束线程,线程传参
1. 线程函数
任何事情都有个开始,线程函数
就是新线程的开始入口。 线程函数必须是callable
和无返回值的。
普通函数 例如上面例子中的简单形式void func(void *params);
可调用类型的实例
class ThreadTask {
private:
size_t count_ = 0;
public:
explicit ThreadTask (size_t count) : count_(count) {}
void operator()() const {
// 定义callable
do_something(this->count_);
}
};
ThreadTask task{
42}; // 初始化可调用类型的实例
std::thread wk_thread{
task}; // 创建并初始化和运行新线程 // 列表初始化
注意: 虽然callable的实例看起来和函数用法一样,但是其本质上仍然是一个类的对象,因此在传入线程进行初始化时,其会被拷贝
到线程空间,因此callable的类在这里必须做好完善的拷贝控制(参拷贝构造函数)
2. 线程启动
线程随着thread类型实例的创建而创建,因此线程就变成了如同实例一样的资源,由C++提供统一的接口进行管理。
创建线程的三种不同的方式: