0
点赞
收藏
分享

微信扫一扫

C++ | C++多线程编程


C++ | C++多线程编程

C++ 多线程

多线程是多任务处理的一种特殊形式,多任务处理允许让电脑同时运行两个或两个以上的程序。
一般情况下,两种类型的多任务处理:基于进程和基于线程

  • 基于进程的多任务处理程序的并发执行
  • 基于线程的多任务处理同一程序的片段的并发执行

C++ | C++多线程编程_c语言

创建线程

PTHREAD_CREATE(3)           Linux Programmer's Manual          PTHREAD_CREATE(3)

NAME
       pthread_create - create a new thread

SYNOPSIS
       #include <pthread.h>

       int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
                          void *(*start_routine) (void *), void *arg);

       Compile and link with -pthread.
RETURN VALUE
       On success, pthread_create() returns 0; on error, it returns an error number, 
       and the contents of *thread are undefined.

thread

指向线程标识符的指针

attr

设置线程属性,NULL表示缺省

start_routine

线程运行函数的起始地址

arg

函数运行的参数

线程退出

PTHREAD_EXIT(3)                                                        Linux Programmer's Manual                                                        PTHREAD_EXIT(3)

NAME
       pthread_exit - terminate calling thread

SYNOPSIS
       #include <pthread.h>

       void pthread_exit(void *retval);

       Compile and link with -pthread.

DESCRIPTION
       The  pthread_exit() function terminates the calling thread and returns a value via retval that (if the thread is joinable) is available to another thread in the
       same process that calls pthread_join(3).

       Any clean-up handlers established by pthread_cleanup_push(3) that have not yet been popped, are popped (in the reverse of the order in which they  were  pushed)
       and  executed.   If  the  thread  has any thread-specific data, then, after the clean-up handlers have been executed, the corresponding destructor functions are
       called, in an unspecified order.

       When a thread terminates, process-shared resources (e.g., mutexes, condition variables, semaphores, and file descriptors) are not released, and functions regis‐
       tered using atexit(3) are not called.

       After  the last thread in a process terminates, the process terminates as by calling exit(3) with an exit status of zero; thus, process-shared resources are re‐
       leased and functions registered using atexit(3) are called.

RETURN VALUE
       This function does not return to the caller.

ERRORS
       This function always succeeds.

CONFORMING TO
       POSIX.1-2001.

NOTES
       Performing a return from the start function of any thread other than the main thread results in an implicit call to pthread_exit(), using the function's  return
       value as the thread's exit status.

       To allow other threads to continue execution, the main thread should terminate by calling pthread_exit() rather than exit(3).

       The value pointed to by retval should not be located on the calling thread's stack, since the contents of that stack are undefined after the thread terminates.

BUGS
       Currently, there are limitations in the kernel implementation logic for wait(2)ing on a stopped thread group with a dead thread group leader.  This can manifest
       in problems such as a locked terminal if a stop signal is sent to a foreground process whose thread group leader has already called pthread_exit().

SEE ALSO
       pthread_create(3), pthread_join(3), pthreads(7)

COLOPHON
       This page is part of release 3.55 of the Linux man-pages project.  A description of the  project,  and  information  about  reporting  bugs,  can  be  found  at
       http://www.kernel.org/doc/man-pages/.

Linux                                                                          2009-03-30                                                               PTHREAD_EXIT(3)

实例1

/*******************************************************************
 *   > File Name: thread.cpp
 *   > Create Time: 2021年09月24日 11:50:02
 ******************************************************************/
#include <iostream>
#include <pthread.h>
#include <unistd.h>
using namespace std;

#define NUM_PTHREAD     (5)

void* say(void *arg)
{
    cout << "thread, arg:" << *(int*)arg << endl;
    return NULL;
}

int main(int argc, char* argv[])
{
    pthread_t thread[NUM_PTHREAD]; /* 定义5个线程标识符 */
    for(int i; i< NUM_PTHREAD; i++)
    {
        pthread_create(&thread[i], NULL, say, (void*)&i); /* 创建线程 */
        sleep(1);
    }
    pthread_exit(NULL); /* 结束线程 */

    return 0;
}

编译、运行:

PS E:\fly-prj\cplusplus\day18> make 
g++ -o thread thread.cpp -g -Wall -O0 -lpthread
PS E:\fly-prj\cplusplus\day18> .\thread.exe
thread, arg:1
thread, arg:2
thread, arg:3
thread, arg:4

实例2

/*******************************************************************
 *   > File Name: thread1.cpp
 *   > Create Time: 2021年09月24日 12:41:44
 ******************************************************************/
#include <iostream>
#include <pthread.h>
#include <unistd.h>
using namespace std;

#define THREAD_NUM      (5)

void *say(void *args)
{
    cout << " thread ID: " << *((int *)args) << endl;
    pthread_exit(NULL);
    return (void *)0;
}

int main(int argc, char* argv[])
{
    pthread_t thread[THREAD_NUM];
    int indexs[THREAD_NUM];
    for(int i = 0; i < THREAD_NUM; ++i)
    {
        cout << "main(), create thread " << i << endl;
        indexs[i] = i;
        if(pthread_create(&thread[i], NULL, say, (void *)&(indexs[i])))
        {
            cout << "pthread_create error." << endl;
            return (-1);
        }
        sleep(1);
    }
    pthread_exit(NULL);

    return 0;
}

编译、运行:

PS E:\fly-prj\cplusplus\day18> make 
g++ -o thread1 thread1.cpp -g -Wall -O0 -lpthread
PS E:\fly-prj\cplusplus\day18> .\thread1.exe
main(), create thread 0
 thread ID: 0
main(), create thread 1
 thread ID: 1
main(), create thread 2
 thread ID: 2
main(), create thread 3
 thread ID: 3
main(), create thread 4
 thread ID: 4

向线程传递参数

实例3

/*******************************************************************
 *   > File Name: thread_args.cpp
 *   > Create Time: 2021年09月24日 13:03:15
 ******************************************************************/
#include <iostream>
#include <unistd.h>
#include <pthread.h>
using namespace std;

#define THREAD_NUM      (5)
typedef struct thread_args{
    int id;
    char *name;
}THREAD_ARGS, *pTHREAD_ARGS;

void* say(void *args)
{	/* 传递多个参数 */
    cout << "id: " << ((pTHREAD_ARGS)args)->id << endl;
    cout << "name: " << ((pTHREAD_ARGS)args)->name << endl;
    pthread_exit(NULL);
}

int main(int argc, char* argv[])
{
    THREAD_ARGS args[THREAD_NUM];
    pthread_t threadid[THREAD_NUM];

    for(int i=0; i< THREAD_NUM; i++){
       args[i].id = i;
       args[i].name = "Thread test."; 
       threadid[i] = (pthread_t)i;
       if(pthread_create(&threadid[i], NULL, say, (void*)&args[i])){
           cout << "pthread_create error." << endl;exit(-1);
       }
       sleep(1); // 不加,可能出现栈溢出
    }
    pthread_exit(NULL);

    return 0;
}

编译、运行:

PS E:\fly-prj\cplusplus\day18> make 
g++ -o thread_args thread_args.cpp -g -Wall -O0 -lpthread
thread_args.cpp: 在函数‘int main(int, char**)’中:
   33 |        args[i].name = "Thread test.";
      |                       ^~~~~~~~~~~~~~
thread_args.cpp:34:22: 警告:将一个整数转换为大小不同的指针 [-Wint-to-pointer-cast]
   34 |        threadid[i] = (pthread_t)i;
      |                      ^~~~~~~~~~~~
PS E:\fly-prj\cplusplus\day18> .\thread_args.exe
id: 0
name: Thread test.
id: 1
name: Thread test.
id: 2
name: Thread test.
id: 3
name: Thread test.
id: 4
name: Thread test.

连接和分离线程

int pthread_join(pthread_t thread, void **retval); //加入一个终止的线程

int pthread_detach(pthread_t thread); //分离线程

pthread_join()子程序阻碍调用程序,直到指定的 threadid 线程终止为止。当创建一个线程时,它的某个属性会定义它是否是可连接的(joinable)或可分离的(detached)。只有创建时定义为可连接的线程才可以被连接。如果线程创建时被定义为可分离的,则它永远也不能被连接。

实例4

/******************************************************************* *   > File Name: pthread.cpp *   > Create Time: 2021年09月24日 23:43:58 ******************************************************************/#include <iostream>#include <cstdlib>#include <pthread.h>#include <unistd.h>using namespace std;#define NUM_THREADS     (5)void *wait(void *t){    long tid;    tid = (long)t;    sleep(1);    cout << "Sleep in thread " << endl;    cout << "Thread with id: " << tid << "...exiting" << endl;    pthread_exit(NULL);}int main(int argc, char* argv[]){    int rc;    int i;    pthread_t threads[NUM_THREADS];    pthread_attr_t attr;    void *status;    pthread_attr_init(&attr); /*初始化线程属性对象*/    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); /* 设置线程的分离属性 */    for(i = 0; i< NUM_THREADS; i++){        cout << "main() : creating thread, " << i << endl;        rc = pthread_create(&threads[i], NULL, wait, (void*)&i); /* 创建线程 */        if(rc){            cout << "Error: unable to create thread." << endl;             exit(-1);        }    }    // 删除属性,并等待其他线程    pthread_attr_destroy(&attr);    for(i = 0; i< NUM_THREADS; i++){        rc = pthread_join(threads[i], &status);        if(rc){            cout << "Error: unable to join, " << rc << endl;            exit(-1);        }        cout << "Main: completed thread id :" << i;        cout << " exiting with status: " << status << endl;     }    cout << "Main: program exiting." << endl;    pthread_exit(NULL); /*结束当前线程*/    return 0;}

编译、运行:

PS D:\study\cplusplus\day9> make
g++ -o pthread pthread.cpp -g -Wall -lpthread
PS D:\study\cplusplus\day9> .\pthread.exe
main() : creating thread, 0
main() : creating thread, 1
main() : creating thread, 2
main() : creating thread, 3
main() : creating thread, 4
Sleep in thread
Sleep in thread Sleep in thread Sleep in thread Sleep in thread



Thread with id: 4294953992Thread with id: Thread with id: Thread with id: Thread with id: ...exiting4294953992429495399242949539924294953992
...exiting...exiting...exiting...exiting



Main: completed thread id :0 exiting with status: 0
Main: completed thread id :1 exiting with status: 0
Main: completed thread id :2 exiting with status: 0
Main: completed thread id :3 exiting with status: 0
Main: completed thread id :4 exiting with status: 0
Main: program exiting.

C++ 11 标准线程库(std::thread)

五个头文件:

  • <atomic>引入std::atomicstd::atomic_flag,定义了原子操作
  • <thread>声明了std::threadstd::this_thread命名空间
  • <mutex>声明了与互斥量mutex相关的类
  • <condition_variable>声明了与条件变量相关的类
  • <future>

实例5

/*******************************************************************
 *   > File Name: pthread1.cpp
 *   > Create Time: 2021年09月25日 10:29:50
 ******************************************************************/
#include <iostream>
#include <thread>
using namespace std;

std::thread::id main_thread_id = std::this_thread::get_id();

void hello()
{
    std::cout << "Hello Concurrent World\n";
    if(main_thread_id == std::this_thread::get_id()){
        std::cout << "This is the main thread.\n";
    }else{
        std::cout << "This is not the main thread.";
    }
}

void pause_thread(int n){
    std::this_thread::sleep_for(std::chrono::seconds(n));
    std::cout << "pause of " << n << "seconds ended\n";
}

int main(int argc, char* argv[])
{
    std::thread t(hello);
    std::cout << t.hardware_concurrency() << std::endl;  // 可以并发执行多个
    std::cout << "native_handle" << t.native_handle() << std::endl; // 可以并发执行多个

    t.join();
    std::thread a(hello);
    a.detach();
    std::thread threads[5]; /* 默认构造函数 */

    std::cout << "Spawning 5 threads...\n" << endl;
    for(int i = 0; i< 5; i++){
        threads[i] = std::thread(pause_thread, i+1);
    }
    std::cout << "Done spawning threads. Now waiting for them to join:\n";
    for(auto &thread:threads){
        thread.join();
    }
    std::cout << "All threads joined\n";

    return 0;
}

编译、运行:

PS D:\study\cplusplus\day9> make
g++ -o pthread pthread.cpp -g -Wall -std=c++11 -lpthread
g++ -o pthread1 pthread1.cpp -g -Wall -std=c++11 -lpthread
PS D:\study\cplusplus\day9> .\pthread1.exe
Hello Concurrent World
4This is not the main thread.
native_handle0x800074630
Hello Concurrent World
Spawning 5 threads...
This is not the main thread.
Done spawning threads. Now waiting for them to join:
pause of 1seconds ended
pause of 2seconds ended
pause of 3seconds ended
pause of 4seconds ended
pause of 5seconds ended
All threads joined

std::thread构造函数

默认构造函数

thread() noexceped;

初始化构造函数

template <class Fn, class ...Args> explicit thread(Fn&& fn, Args&&...args);

拷贝构造函数[delected]

thread(const thread &) = delete;

Move构造函数

thread(thread&& x) noexcept;

  • 默认构造函数,创建一个空的std::thread执行对象。
  • 初始化构造函数,创建一个std::thread对象,该std::thread对象可被joinable,新产生的线程会调用fn函数,该函数的参数由args给出。
  • 拷贝构造函数(被禁用),意味着std::thread对象不可拷贝构造。
  • Move构造函数,move构造函数(move语义是C++11新出现的概念,详见附录),调用成功后x不代表任何std::thread执行对象。

注意:可被 joinable std::thread 对象必须在他们销毁之前被主线程 join 或者将其设置为 detached.

实例6

/*******************************************************************
 *   > File Name: std_thread.cpp
 *   > Create Time: 2021年09月25日 18:08:54
 ******************************************************************/
#include <iostream>
#include <utility>
#include <thread>
#include <chrono>
#include <functional>
#include <atomic>

using namespace std;

void f1(int n){
    for(int i = 0; i< 5; ++i){
        std::cout << "Thread f1 " << n << " executing\n";
        std::this_thread::sleep_for(std::chrono::milliseconds(10));// 睡眠10毫秒
    }
}

void f2(int& n){
    for(int i = 0; i< 5; ++i){
        std::cout << "Thread f2 executing\n";
        ++n;
        std::this_thread::sleep_for(std::chrono::milliseconds(10));// 睡眠10毫秒
    }
}

int main(int argc, char* argv[])
{
    int n = 0;
    std::thread t1; // t1 is not a thread ,创建一个空的thread对象
    std::thread t2(f1, n+1); // pass by value
    std::thread t3(f2, std::ref(n)); // pass by reference
    std::thread t4(std::move(t3)); // t4 is now running f2().t3 is no longer a thread
    t2.join(); // 等待t2线程结束,主线程再结束
    t4.join(); // 等待t4线程结束,主线程再结束
    std::cout << "Final value of n is " << n << "\n";

    return 0;
}

编译、运行:

PS D:\study\cplusplus\day9> make
g++ -o std_thread std_thread.cpp -g -Wall -std=c++11 -lpthread
PS D:\study\cplusplus\day9> .\std_thread.exe
Thread f1 1 executing
Thread f2 executing
Thread f1 1 executing
Thread f2 executing
Thread f1 1 executing
Thread f2 executing
Thread f1 1 executing
Thread f2 executing
Thread f1 1 executing
Thread f2 executing
Final value of n is 5

std::thread 赋值操作

Move赋值操作

thread& operator=(thread&& rhs) noexcept;

拷贝赋值操作 [delected]

thread& operator=(const thread&) = delete;

  • Move赋值操作(1),如果当前对象不可用joinable,需传递一个右值引用(rhs)给move赋值操作;如果当前对象可被joinable,则会调用terminate()报错。
  • 拷贝赋值操作(2),被禁用,因此std::thread对象不可拷贝赋值。

实例7

/*******************************************************************
 *   > File Name: std_thread1.cpp
 *   > Create Time: 2021年09月26日 22:52:04
 ******************************************************************/
#include <stdio.h>
#include <stdlib.h>

#include <chrono>   // std::chrono::seconds
#include <iostream> // std:cout
#include <thread>   // std::thread, std::this_thread::sleep_for
using namespace std;

void thread_task(int n){
    std::this_thread::sleep_for(std::chrono::seconds(n));
    std::cout << "Hello thread "
        << std::this_thread::get_id()
        << "  paused " << n << "seconds " << std::endl;
}

int main(int argc, char* argv[])
{
    std::thread threads[5];
    std::cout << "Spawning 5 threads...\n";
    for(int i = 0; i < 5; i++){
        threads[i] = std::thread(thread_task, i + 1); 
    }
    std::cout << "Done spawning threads! Now wait for them to join\n";
    for(auto& t: threads){
        t.join();
    }
    std::cout << "All threads joined.\n";

    return 0;
}

编译、运行:

PS D:\study\cplusplus\day9> make
g++ -o std_thread1 std_thread1.cpp -g -Wall -std=c++11 -lpthread
PS D:\study\cplusplus\day9> .\std_thread1.exe
Spawning 5 threads...
Done spawning threads! Now wait for them to join
Hello thread 0x800084640  paused 1seconds
Hello thread 0x800084740  paused 2seconds
Hello thread 0x800084840  paused 3seconds
Hello thread 0x800084960  paused 4seconds
Hello thread 0x800084a80  paused 5seconds
All threads joined.

其他成员函数

get_id:获取线程ID,返回一个类型为std::thread::id的对象。

实例8(get_id

/*******************************************************************
 *   > File Name: std_thread_get_id.cpp
 *   > Create Time: 2021年09月26日 23:07:35
 ******************************************************************/
#include <iostream>
#include <thread>
#include <chrono>
using namespace std;

void foo(){
    std::this_thread::sleep_for(std::chrono::seconds(1));
}

int main(int argc, char* argv[])
{
    std::thread t1(foo);
    std::thread::id t1_id = t1.get_id();

    std::thread t2(foo);
    std::thread::id t2_id = t2.get_id();

    cout << "t1's id: " << t1_id << endl;
    cout << "t2's id: " << t2_id << endl;

    t1.join();
    t2.join();

    return 0;
}

编译、运行:

PS D:\study\cplusplus\day9> make
g++ -o std_thread_get_id std_thread_get_id.cpp -g -Wall -std=c++11 -lpthread
PS D:\study\cplusplus\day9> .\std_thread_get_id.exe
t1's id: 0x800074630
t2's id: 0x800074730

实例9(joinable

/*******************************************************************
 *   > File Name: std_thread_joinable.cpp
 *   > Create Time: 2021年09月26日 23:18:07
 ******************************************************************/
#include <iostream>
#include <thread>
#include <chrono>
using namespace std;

void foo(){
    std::this_thread::sleep_for(std::chrono::seconds(1));
}

int main(int argc, char* argv[])
{
    std::thread t;
    std::cout << "Before starting ,joinable: " << t.joinable() << endl;

    t = std::thread(foo);
    std::cout << "After starting, joinable: " << t.joinable() << endl;

    t.join();

    return 0;
}

编译、运行:

PS D:\study\cplusplus\day9> make
g++ -o std_thread_joinable std_thread_joinable.cpp -g -Wall -std=c++11 -lpthread
PS D:\study\cplusplus\day9> .\std_thread_joinable.exe
Before starting ,joinable: 0
After starting, joinable: 1

实例10(join

join: Join 线程,调用该函数会阻塞当前线程,直到由 *this 所标示的线程执行完毕 join 才返回。

/*******************************************************************
 *   > File Name: std_thread_joinable1.cpp
 *   > Create Time: 2021年09月26日 23:25:54
 ******************************************************************/
#include <iostream>
#include <thread>
#include <chrono>
using namespace std;

void foo(){
    std::this_thread::sleep_for(std::chrono::seconds(1));
}

void bar(){
    std::this_thread::sleep_for(std::chrono::seconds(1));
}

int main(int argc, char* argv[])
{
    std::cout << "starting first helper...\n";
    std::thread helper1(foo);

    std::cout << "starting second helper...\n";
    std::thread helper2(bar);

    std::cout << "waiting for helpers to finish..." << std::endl;
    helper1.join();
    helper2.join();

    std::cout << "done~\n";

    return 0;
}

编译、运行:

PS D:\study\cplusplus\day9> make                         
g++ -o std_thread_joinable1 std_thread_joinable1.cpp -g -Wall -std=c++11 -lpthread
PS D:\study\cplusplus\day9> .\std_thread_joinable1.exe
starting first helper...
starting second helper...
waiting for helpers to finish...
done~

实例11(detach

detach: Detach 线程。 将当前线程对象所代表的执行实例与该线程对象分离,使得线程的执行可以单独进行。一旦线程执行完毕,它所分配的资源将会被释放。

调用 detach 函数之后:

  • *this 不再代表任何的线程执行实例。
  • joinable() == false
  • get_id() == std::thread::id()

另外,如果出错或者 joinable() == false,则会抛出 std::system_error

/*******************************************************************
 *   > File Name: std-pthread-detach.cpp
 *   > Create Time: 2021年10月 1日 12:13:42
 ******************************************************************/

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

void independentThread(){
    std::cout << "Starting concurrent thread.\n";
    std::this_thread::sleep_for(std::chrono::seconds(2));
    std::cout << "Exiting concurrent thread.\n";
}

void threadCaller(){
    std::cout << "Starting thread caller.\n";
    std::thread t(independentThread);
    t.detach();
    std::this_thread::sleep_for(std::chrono::seconds(2));
    std::cout << "Exiting thread caller.\n";
}

int main(int argc, char* argv[])
{
    threadCaller();
    std::this_thread::sleep_for(std::chrono::seconds(5));
    return 0;
}

编译、运行:

PS D:\study\cplusplus\day12> make
g++ -o std-pthread-detach std-pthread-detach.cpp -g -Wall -std=c++11
PS D:\study\cplusplus\day12> .\std-pthread-detach.exe
Starting thread caller.
Starting concurrent thread.
Exiting concurrent thread.
Exiting thread caller.
PS D:\study\cplusplus\day12>

实例12(swap

Swap 线程,交换两个线程对象所代表的底层句柄(underlying handles)。

/*******************************************************************
 *   > File Name: std-thread-swap.cpp
 *   > Create Time: 2021年10月 1日 13:20:40
 ******************************************************************/

#include <iostream>
#include <thread>
#include <chrono>

void foo(){
  std::this_thread::sleep_for(std::chrono::seconds(1));
}

void bar(){
  std::this_thread::sleep_for(std::chrono::seconds(1));
}

int main()
{
  std::thread t1(foo);
  std::thread t2(bar);

  std::cout << "thread 1 id: " << t1.get_id() << std::endl;
  std::cout << "thread 2 id: " << t2.get_id() << std::endl;

  std::swap(t1, t2);

  std::cout << "after std::swap(t1, t2):" << std::endl;
  std::cout << "thread 1 id: " << t1.get_id() << std::endl;
  std::cout << "thread 2 id: " << t2.get_id() << std::endl;

  t1.swap(t2);

  std::cout << "after t1.swap(t2):" << std::endl;
  std::cout << "thread 1 id: " << t1.get_id() << std::endl;
  std::cout << "thread 2 id: " << t2.get_id() << std::endl;

  t1.join();
  t2.join();
}

编译、运行:

PS D:\study\cplusplus\day12>make
g++ -o std-thread-swap std-thread-swap.cpp -g -Wall -std=c++11
PS D:\study\cplusplus\day12> .\std-thread-swap.exe
thread 1 id: 0x800074630
thread 2 id: 0x800074730
after std::swap(t1, t2):
thread 1 id: 0x800074730
thread 2 id: 0x800074630
after t1.swap(t2):
thread 1 id: 0x800074630
thread 2 id: 0x800074730

实例13(native_handle

返回 native handle(由于 std::thread 的实现和操作系统相关,因此该函数返回与 std::thread 具体实现相关的线程句柄,例如在符合 Posix 标准的平台下(如 Unix/Linux)是 Pthread 库)。

/*******************************************************************
 *   > File Name: std-thread-native-handle.cpp
 *   > Create Time: 2021年10月 1日 15:44:59
 ******************************************************************/
#include <thread>
#include <iostream>
#include <chrono>
#include <cstring>
#include <pthread.h>
#include <mutex>

std::mutex iomutex;
void f(int num)
{
  std::this_thread::sleep_for(std::chrono::seconds(1));

 sched_param sch;
 int policy; 
 pthread_getschedparam(pthread_self(), &policy, &sch);
 std::lock_guard<std::mutex> lk(iomutex);
 std::cout << "Thread " << num << " is executing at priority "
           << sch.sched_priority << '\n';
}

int main()
{
  std::thread t1(f, 1), t2(f, 2);

  sched_param sch;
  int policy; 
  pthread_getschedparam(t1.native_handle(), &policy, &sch);
  sch.sched_priority = 20;
  if(pthread_setschedparam(t1.native_handle(), SCHED_FIFO, &sch)) {
      std::cout << "Failed to setschedparam: " << std::strerror(errno) << '\n';
  }

  t1.join();
  t2.join();
}

运行:

PS D:\study\cplusplus\day12> .\std-thread-native-handle.exe
Thread 1 is executing at priority 20
Thread 2 is executing at priority 16

实例14(hardware_concurrency [static]

检测硬件并发特性,返回当前平台的线程实现所支持的线程并发数目,但返回值仅仅只作为系统提示(hint)。

/*******************************************************************
 *   > File Name: std-thread1.cpp
 *   > Create Time: 2021年10月 1日 15:49:00
 ******************************************************************/
#include <iostream>
#include <thread>

int main() {
  unsigned int n = std::thread::hardware_concurrency();
  std::cout << n << " concurrent threads are supported.\n";
}

运行:

PS D:\study\cplusplus\day12> .\std-thread1.exe
4 concurrent threads are supported.

std::this_thread 命名空间中相关辅助函数介绍

get_id: 获取线程 ID。

yield: 当前线程放弃执行,操作系统调度另一线程继续执行。

sleep_until: 线程休眠至某个指定的时刻(time point),该线程才被重新唤醒。

sleep_for: 线程休眠某个指定的时间片(time span),该线程才被重新唤醒,不过由于线程调度等原因,实际休眠时间可能比 sleep_duration 所表示的时间片更长。

举报

相关推荐

c++多线程

C++多线程

Linux C/C++多线程

多线程 c c++ Qt

c++并发编程/多线程 thread 库

c++多线程并发

0 条评论