一 点睛
C++11提供了一个命名空间this_thread来引用当前线程,该命名空间有4个有用的函数,get_id,yield,sleep_until,sleep_for。
get_id是用来获取线程ID的。
其他3个函数都和时间相关,下面分别进行实战演练。
二 yield让出CPU时间
1 点睛
yield函数:调用该函数的线程放弃执行,回到就绪态。
我们创建10个线程,每个线程中让一个变量从一累加到一百万,谁先完成打印它的编号,以此排名。为了公平起见,创建线程的时候,先不让占用CPU时间,一直到main线程改变全局变量的值,各个线程才一起开始累加。
2 代码
#include <iostream> // std::cout
#include <thread> // std::thread, std::this_thread::yield
#include <atomic> // std::atomic
using namespace std;
atomic<bool> ready(false);
void thfunc(int id)
{
while (!ready) //一直等待,直到main线程中重置全局变量ready
this_thread::yield(); //让出自己的CPU时间片
for (volatile int i = 0; i < 1000000; ++i) //开始累加到一百万
{}
cout << id<<",";//输出的是排名,先完成先打印
}
int main()
{
thread threads[10]; //定义10个线程对象
cout << "race of 10 threads that count to 1 million:\n";
for (int i = 0; i < 10; ++i)
threads[i] = thread(thfunc, i); //启动线程,把i当做参数传入线程函数,用于标记线程的序号
ready = true; //重置全局变量
for (auto& th : threads)
th.join(); //等待10个线程全部结束
cout << '\n';
return 0;
}
3 运行
[root@localhost test]# g++ -o test test.cpp -lpthread -std=c++11
[root@localhost test]# ./test
race of 10 threads that count to 1 million:
9,4,5,0,1,2,6,7,8,3,
4 说明
线程刚刚启动的时候,一直在while循环中让出自己的CPU时间,这就是yield的作用,this_thread在子线程中使用,代表这个子线程本身。
三 暂停线程到下一分钟
1 代码
#include <iostream> // std::cout
#include <thread> // std::this_thread::sleep_until
#include <chrono> // std::chrono::system_clock
#include <ctime> // std::time_t, std::tm, std::localtime, std::mktime
#include <time.h>
#include <stddef.h>
using namespace std;
void getNowTime() //获取并打印当前时间
{
timespec time;
struct tm nowTime;
clock_gettime(CLOCK_REALTIME, &time); //获取相对于1900到现在的秒数
localtime_r(&time.tv_sec, &nowTime);
char current[1024];
printf(
"%04d-%02d-%02d %02d:%02d:%02d\n",
nowTime.tm_year + 1900,
nowTime.tm_mon+1,
nowTime.tm_mday,
nowTime.tm_hour,
nowTime.tm_min,
nowTime.tm_sec);
}
int main()
{
using std::chrono::system_clock;
std::time_t tt = system_clock::to_time_t(system_clock::now());
struct std::tm * ptm = std::localtime(&tt);
getNowTime(); // 打印当前时间
cout << "Waiting for the next minute to begin...\n";
++ptm->tm_min; //加一分钟
ptm->tm_sec = 0; //秒数设置为0
//暂停执行,到下一整分执行
this_thread::sleep_until(system_clock::from_time_t(mktime(ptm)));
getNowTime(); //打印当前时间
return 0;
}
2 运行
[root@localhost test]# g++ -o test test.cpp -lpthread -std=c++11
[root@localhost test]# ./test
2019-04-13 08:24:29
Waiting for the next minute to begin...
2019-04-13 08:25:00
3 说明
main线程从sleep_until处开始挂起,然后到下一个整分时间再继续执行。
四 暂停线程5秒
1 代码
#include <iostream> // std::cout, std::endl
#include <thread> // std::this_thread::sleep_for
#include <chrono> // std::chrono::seconds
int main()
{
std::cout << "countdown:\n";
for (int i = 5; i > 0; --i)
{
std::cout << i << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(1)); //暂停1秒
}
std::cout << "Lift off!\n";
return 0;
}
2 运行
[root@localhost test]# g++ -o test test.cpp -lpthread -std=c++11
[root@localhost test]# ./test
countdown:
5
4
3
2
1
Lift off!