多线程, 简单的理解就是让我们可以同时做多件事情, 以下为简单例子.
#include <iostream>
#include <thread>
using namespace std;
void first() {
cout << "do one thing" << endl;
}
void second() {
cout << "do another thing" << endl;
}
int main() {
thread t1(first);
thread t2(second);
t1.join();
t2.join();
}
编译命令需要加上 -lpthread 参数
而一般谈到多线程就会涉及到上锁的问题, 为什么要上锁? 是为了线程安全. 比方说我有两个线程, 都要拿到一个唯一的数据(只能被拿一次), 如果不上锁, 那么就很有可能两个线程同时拿, 数据就被拿了两次. 如果我们上锁, 我们就限制了拿的操作在某个时间只能有一个线程做, 如果这个时候其他线程也想做就得等待. 这样就保证了线程安全.
例子:
#include <iostream>
#include <mutex>
#include <thread>
#include <vector>
using namespace std;
std::mutex mtx;
int a = 1;
void test() {
std::unique_lock<std::mutex> lck(mtx); (这一行就是上锁,去掉就不线程安全了)
if(a) {
cout << a << endl;
a--;
}
else
cout << "nothing" << endl;
}
int main(void){
std::vector<thread> v;
int n = 10;
while(n--)
v.push_back(thread(test));
for(auto &i: v)
i.join();
}
这个例子使用了unique_lock锁(还有lock_guard等种类的锁), 我们设置了一个唯一的数a, 它一被拿就马上置0,然后就不能再拿了, 上锁就能实现这样的效果,输出为
1
nothing
nothing
nothing
nothing
nothing
nothing
nothing
nothing
nothing
而如果把上锁的那一行注释掉, 可以试一下看看输出, 很明显数a被拿了多次, 都通过了if(a)的判断, 然后输出也就会有本不应该有的负数, 也就不线程安全了.
也可以使用lock()和unlock()函数,手动加锁以及释放锁
#include <iostream>
#include <mutex>
#include <thread>
#include <vector>
using namespace std;
std::mutex mtx;
int a = 1;
void test() {
mtx.lock();
if(a) {
cout << a << endl;
a--;
}
else
cout << "nothing" << endl;
mtx.unlock();
}
int main(void){
std::vector<thread> v;
int n = 10;
while(n--)
v.push_back(thread(test));
for(auto &i: v)
i.join();
}