c++ multithreading: the use of this_thread

In C++11, not only the thread class is added, but also a thread namespace std::this_thread is added, which is provided in this namespace. Through these member 四个公共的成员函数functions, related operations can be performed on the current thread

1. get_id()

The thread can be obtained by calling get_id() the method . The function prototype is as follows:当前线程 ID

thread::id get_id() noexcept;

The sample code corresponding to the function usage is as follows:

#include <iostream>
#include <thread>
using namespace std;

void func()
{
    
    
    cout << "子线程: " << this_thread::get_id() << endl;
}

int main()
{
    
    
    cout << "主线程: " << this_thread::get_id() << endl;
    thread t(func);
    t.join();
}

The program starts and starts to execute the main() function. At this time, there is only one thread, which is the main thread. After the child thread object t is created, the specified function func() will be executed in the child thread, and the thread ID of the current thread this_thread::get_id() can .

2. sleep_for()

Similarly, after the thread is created, it also has these five states: creation state, ready state, running state, blocking state (suspended state), exit state (termination state) . The transition between states is the same, please refer to the process, No more details here.

There are many similarities between the execution of threads and processes. Multiple threads started in the computer need to occupy CPU resources, but the number of CPUs is limited and each CPU cannot process multiple tasks at the same time. ·In order to achieve concurrent processing, multiple threads are time-division multiplexed with CPU time slices, and quickly and alternately process the tasks in each thread·. Therefore, multiple threads need to 争抢CPU时间片be executed if they are grabbed, and cannot be executed if they cannot be grabbed (because all threads have the same priority by default, and the kernel will also schedule from them, and it will not happen that a thread will never be able to grab a CPU time slice. Condition).

One is provided in the namespace this_thread 休眠函数 sleep_for(). The thread calling this function will immediately 从运行态变成阻塞态sleep for a certain period of time in this state, because 阻塞态的线程已经让出了 CPU 资源the code will not be executed, so there is no burden on the CPU during the thread sleep process. The prototype of this function is as follows. The parameter needs to specify a sleep duration, which is a period of time:

template <class Rep, class Period>
void sleep_for (const chrono::duration<Rep,Period>& rel_time);

The sample program is as follows:

#include <iostream>
#include <thread>
#include <chrono>
using namespace std;

void func()
{
    
    
    for (int i = 0; i < 10; ++i)
    {
    
    
        this_thread::sleep_for(chrono::seconds(1));
        cout << "子线程: " << this_thread::get_id() << ", i = " << i << endl;
    }
}

int main()
{
    
    
    thread t(func);
    t.join();
}

After this_thread::sleep_for(chrono::seconds(1)); is used in the for loop of the func() function, the program will be blocked for 1 second each time the loop is run, that is to say, the output will only be performed every 1 second. Note that: 程序休眠完成之后,会从阻塞态重新变成就绪态,就绪态的线程需要再次争抢 CPU 时间片,抢到之后才会变成运行态,这时候程序才会继续向下运行.

3. sleep_until()

Another sleep function sleep_until() is provided in the namespace this_thread, which differs from sleep_for() in that its parameter types are different

  • sleep_until(): Specifies the thread 阻塞到某一个指定的时间点 time_point类型, then unblocks it
  • sleep_for(): Specify thread 阻塞一定的时间长度 duration type, then unblock

The function prototype of this function is as follows:

template <class Clock, class Duration>
void sleep_until (const chrono::time_point<Clock,Duration>& abs_time);

The sample program is as follows:

#include <iostream>
#include <thread>
#include <chrono>
using namespace std;

void func()
{
    
    
    for (int i = 0; i < 10; ++i)
    {
    
    
        // 获取当前系统时间点
        auto now = chrono::system_clock::now();
        // 时间间隔为2s
        chrono::seconds sec(2);
        // 当前时间点之后休眠两秒
        this_thread::sleep_until(now + sec);
        cout << "子线程: " << this_thread::get_id() << ", i = " << i << endl;
    }
}

int main()
{
    
    
    thread t(func);
    t.join();
}

sleep_until() 和 sleep_for() The functions of the functions are the same, except that the former blocks threads based on time points, and the latter blocks threads based on time periods. During the project development process, the optimal solution can be selected according to the actual situation.

4. yield()

The namespace this_thread provides one 非常绅士的函数 yield(), after calling this function in the thread, 处于运行态的线程会主动让出自己已经抢到的 CPU 时间片,最终变为就绪态so that other threads have a greater probability of grabbing the CPU time slice. When using this function, you need to pay attention to it. 线程调用了 yield () 之后会主动放弃 CPU 资源但是这个变为就绪态的线程会马上参与到下一轮 CPU 的抢夺战中It does not rule out that it can continue to grab CPU time slices. This is a matter of probability.

void yield() noexcept;

The sample program corresponding to the function is as follows:

#include <iostream>
#include <thread>
using namespace std;

void func()
{
    
    
    for (int i = 0; i < 100000000000; ++i)
    {
    
    
        cout << "子线程: " << this_thread::get_id() << ", i = " << i << endl;
        this_thread::yield();
    }
}

int main()
{
    
    
    thread t(func);
    thread t1(func);
    t.join();
    t1.join();
}

In the above program, executing the for loop in func() will take a lot of time. In extreme cases, if the current thread occupies CPU resources and does not release them, tasks in other threads cannot be processed, or the thread can grab the CPU time slice, resulting in no chance for tasks in other threads to be executed. The solution is to let the thread voluntarily give up CPU resources every time the loop is executed, and grab the CPU time slice again with other threads. If other threads grab the CPU time slice, they can perform corresponding tasks.

Conclusion:
The purpose of std::this_thread::yield() is that 避免一个线程长时间占用CPU资源,从而导致多线程处理性能下降
std::this_thread::yield() is to let the current thread actively give up the CPU resources that it currently grabs.但是在下一轮还会继续抢

Guess you like

Origin blog.csdn.net/weixin_38346042/article/details/131371717