目录
一、介绍
C++下可以使用thread加入线程,有两种方式加入线程,分别是join和detach,写法如下:
join这个属于等待线程,join特点是主线程必须等子线程执行完才能退出
int main()
{
printf("这个属于主线程,也就是main的线程\n");
std::thread udp(udpRecv);
udp.join(); //join这个属于子线程,join特点是主线程必须等子线程执行完才能退出
return 0;
}
detach属于分离线程,主线程不需要等待子线程,它和主线程独立
int main()
{
printf("这个属于主线程,也就是main的线程\n");
std::thread udp(udpRecv);
udp.detach();
return 0;
}
二、代码
1.join属于等待线程,一个线程没结束不能执行另一个线程
#include <iostream>
#include <thread>
using namespace std;
void t1()
{
int i = 0;
while (1)
{
printf("%d\n", i++);
}
}
void t2()
{
char c = 'a';
while (1)
{
printf("%c\n",c++);
}
}
int main()
{
thread T1(t1);//入参为函数名
T1.join();
std::cout << "这是主线程\n";
char c = 'a';
while (1)
{
printf("%c\n", c++);
}
return 0;
}
2.detach属于分离线程,主线程和子线程可以同步执行
#include <iostream>
#include <thread>
using namespace std;
void t1()
{
int i = 0;
while (1)
{
printf("%d\n", i++);
}
}
void t2()
{
char c = 'a';
while (1)
{
printf("%c\n",c++);
}
}
int main()
{
thread T1(t1);//入参为函数名
T1.detach();
std::cout << "这是主线程\n";
char c = 'a';
while (1)
{
printf("%c\n", c++);
}
return 0;
}
detach主线程子线程互不干扰,且位置可以随意放置
三、互斥体
当两个线程同时处理一个数据时,如果不对其进行限制,数据可能出现同时被访问和修改的情况,此时会导致数据访问或修改出现问题。为了解决这个问题,一个策略是在线程a访问数据的时候,对数据进行限制,不允许其他线程访问和修改,等线程a处理完毕后,再解除这个限制,也就是mutex互斥体的概念。
如果不使用互斥体,会出现两个线程同时访问同一个数据,如下所示:
如果有互斥体,数据访问就会一个接一个按次序访问,不会出现争抢现象
#include <iostream>
#include <thread>
#include <Windows.h>
#include <mutex>
using namespace std;
mutex mu; //线程互斥对象
int totalNum = 100;
void thread1()
{
while (totalNum > 0)
{
mu.lock(); //同步数据锁
cout <<"线程1输出:"<<totalNum << endl;
totalNum--;
Sleep(1);
mu.unlock(); //解除锁定
}
}
void thread2()
{
while (totalNum > 0)
{
mu.lock();
cout << "线程2输出:" << totalNum << endl;
totalNum--;
Sleep(1);
mu.unlock();
}
}
int main()
{
thread task1(thread1);
thread task2(thread2);
task1.detach();
task2.detach();
system("pause");
return 0;
}