#include
#include
#include
std::mutex mutex;
void fun1()
{
for (int i = 0; i <5 ; ++i) {
std::cout<<"\n" ;
}
}
void fun2(){
for (int i = 0; i < 5; ++i) {
std::cout<<"\n" ;
}
}
int main()
{
std::thread th(fun1);
std::thread t2(fun2);
th.join();
t2.join();
return 0;
}
按照我们的想象,坑定是先打印很多
,再打印
然而,你会发现每次运行结果都不一样,而且与 交替输出。
这是为什么呢?以前学过操作系统,知道线程会竞争资源,我们这里可以把cout输出看作是一种资源,他们都要输出一段字符串,那么必定要竞争输出资源,每次谁得到这个资源,就打印自己的输出,所以就会得到这种输出现象。
操作系统学过,防止资源竞争造成的死锁,一般可以通过加互斥锁避免。
#include
#include
#include
std::mutex mutex;
void fun1()
{
{
std::unique_lock<std::mutex> lock(mutex);
for (int i = 0; i <5 ; ++i) {
std::cout<<"\n" ;
}
}
}
void fun2(){
{
std::unique_lock<std::mutex> lock(mutex);
for (int i = 0; i < 5; ++i) {
std::cout<<"\n" ;
}
}
}
int main()
{
std::thread th(fun1);
std::thread t2(fun2);
th.join();
t2.join();
return 0;
}
#include
#include
#include
std::mutex mutex;
void fun1()
{
{//代码块1
std::unique_lock<std::mutex> lock(mutex);
for (int i = 0; i <5 ; ++i) {
std::cout<<"\n" ;
}
}
for (int i = 0; i <5 ; ++i) {//代码块2
std::cout<<"\n" ;
}
}
void fun2(){
{//代码块3
std::unique_lock<std::mutex> lock(mutex);
for (int i = 0; i < 5; ++i) {
std::cout<<"\n" ;
}
}
for (int i = 0; i < 5; ++i) {//代码块4
std::cout<<"\n" ;
}
}
int main()
{
std::thread th(fun1);
std::thread t2(fun2);
th.join();
t2.join();
return 0;
}
1)当创建好了2个线程th和t2,它们准备开始执行函数。
2)它们都进入函数体发现代码块1和代码块3加了互斥锁,那这样的话只能让代码块1执行完,然后释放锁,代码块3才能获得锁,它才能开始执行。所以我们预期的结果就产生了。
3)但是当代码块1执行完了,代码块2并没有加锁,这时它就和代码块3与代码4形成了竞争关系,所以会产生与 交替输出的现象,理论上也可能产生 与 交替输出(所以最后输出也可能是 与 交替输出)。
4)但是函数执行是顺序的,也就是说代码块2一定在代码块1后执行、代码块4一定在代码块3前执行,也就是说不可能出现在 前输出、 不可能出现在 之前。
#include
#include
#include
std::mutex mutex;
void fun1()
{
{
std::unique_lock<std::mutex> lock(mutex);
for (int i = 0; i <5 ; ++i) {
std::cout<<"\n" ;
}
}
for (int i = 0; i <10 ; ++i) {
std::cout<<"\n" ;
}
}
void fun2(){
{
std::unique_lock<std::mutex> lock(mutex);
for (int i = 0; i < 5; ++i) {
std::cout<<"\n" ;
}
}
for (int i = 0; i < 5; ++i) {
std::cout<<"\n" ;
}
}
int main()
{
std::thread th(fun1);
std::thread t2(fun2);
th.join();
t2.join();
return 0;
}
#include
#include
#include
std::mutex mutex;
void fun1()
{
{
std::unique_lock<std::mutex> lock(mutex);
for (int i = 0; i <5 ; ++i) {
std::cout<<"\n" ;
}
}
std::unique_lock<std::mutex> lock(mutex);
for (int i = 0; i <5 ; ++i) {
std::cout<<"\n" ;
}
}
void fun2(){
{
std::unique_lock<std::mutex> lock(mutex);
for (int i = 0; i < 5; ++i) {
std::cout<<"\n" ;
}
}
for (int i = 0; i < 5; ++i) {
std::cout<<"\n" ;
}
}
int main()
{
std::thread th(fun1);
std::thread t2(fun2);
th.join();
t2.join();
return 0;
}
1)在访问共享资源时,首先申请互斥锁,如果该互斥处于开锁状态,则申请到该锁对象,并立即上锁,防止其他线程访问该资源。如果互斥锁处于锁定状态,默认阻塞当前进程。
2)阻塞(pend)就是任务释放CPU,其他任务可以运行,一般在等待某种资源或信号量的时候出现。