多线程创建
//多线程创建
void print(string s)
{
cout << "i am a new thread:" << s << endl;
}
int main()
{
//move将左值变成右值(右值引用过后的属性是左值)
//thread t1(print, "t1");
//thread t2(move(t1));//调用移动构造
//t2.join();
//多线程创建
vector<thread> vt(5);//创建无参的线程对象:即空线程,不会启动
int i = 0;
for (thread& t : vt)//没提供拷贝构造,使用引用
{
//移动赋值
t = thread(print, "线程"+to_string(i++));//匿名对象 将亡值
}
for (thread& t : vt)
{
t.join();
}
return 0;
}
lambda表达式作为线程参数
//lambda表达式作为线程参数
int main()
{
int n = 100;
auto f = [n](const string& s) mutable{
for (int i = 0; i < n; i++)
{
//n++;//传值捕获参数具有const属性,不能修改,除非mutable修饰
cout << i << ":i am a new thread:" << s << endl;
}
};
//function<void(const string&)> pf = f;//包装器
//pf("abc");
//f("abc");
thread t1(f,"t1");
t1.join();
return 0;
}
线程锁mutex
//线程锁mutex
int main()
{
int n;
cin >> n;
int x = 0;
//存在线程安全的问题
//thread t1([n, &x] (){
// for (int i = 0; i < n; i++)
// {
// x++;
// }
// });
//thread t2([n, &x]() {
// for (int i = 0; i < n; i++)
// {
// x++;
// }
// });
mutex mx;//上锁(锁不支持拷贝)
thread t1([n, &x,&mx]() {
for (int i = 0; i < n; i++)
{
mx.lock();
x++;
mx.unlock();
}
});
thread t2([n, &x,&mx]() {
for (int i = 0; i < n; i++)
{
mx.lock();
x++;
mx.unlock();
}
});
t1.join();
t2.join();
cout << "调用次数:" << x << endl;//只有线程执行完毕才是有效的x
return 0;
}
线程引用接收参数-----ref()
//线程引用接收参数-----ref()
void Count(int n, int& x)//thread的构造函数所调用的函数不能引用接收参数
{
//thread构造函数内部是通过参数列表的方式解析传来的参数
//而且传来的参数是传给构造函数的,而不是直接传给形参的,所以参数推导会出问题
//实参加上ref修饰,或者形参const&修饰
for (int i = 0; i < n; i++)
{
x++;
}
}
int main()
{
int x = 0;
int n; cin >> n;
thread t1(Count, n, ref(x));
t1.join();
cout << "循环次数:" << x << endl;
return 0;
}
异常思索问题--》智能指针
//异常思索问题--》智能指针
void fun()
{
srand(time(nullptr));//设置随机数种子
while (1)
{
int x = rand() % 10;
cout << x << ' ';
if (x == 3)
{
throw exception("异常错误");
}
}
cout << endl;
}
class guardlock
{
public:
guardlock(mutex& m)
:_m(m)//mutex不支持拷贝和赋值
{
_m.lock();
}
~guardlock()
{
_m.unlock();
}
private:
mutex& _m;//成员变量用引用
};
int main()
{
mutex m;
try {
//guardlock gl(m);//不会死锁,最终栈销毁的时候都会先调用析构函数解锁
//lock_guard<mutex> lg(m);//库中
unique_lock<mutex> lg(m);//库中(支持手动上锁和解锁)
fun();
}
catch (exception e)
{
cout << e.what() << endl;
}
return 0;
}
两个线程交替打印奇偶数-->atomic(底层cas)
//两个线程交替打印奇偶数-->atomic(底层cas)
//do {//模拟x++
// old = x;
// newval = old + 1;
//} while (atomic_compare_exchange_weak(&x, &old, newval);
int main()
{
mutex mx;
int i = 0;
//atomic<size_t> i = 0;//原子性的,不运行多执行流同时访问该资源
condition_variable con1;
condition_variable con2;
thread t1([&mx, &i,&con1,&con2]() {
while (i<=1000)
{
unique_lock<mutex> lg(mx);//局部变量,出了作用域自动调用析构
if (i % 2 != 1)
con1.wait(lg);
if (i % 2 == 1)
{
cout << "t1:" << i << endl;
i++;
}
con2.notify_one();
//lg.unlock();
}
});
thread t2([&mx, &i,&con1,&con2]() {
while (i<=1000)
{
unique_lock<mutex> lg(mx);
if (i % 2 != 0)
con2.wait(lg);
if (i % 2 == 0)
{
cout << "t2:" << i << endl;
i++;
}
con1.notify_one();
//lg.unlock();
}
});
t1.join();
t2.join();
return 0;
}