C++ thread编程(Linux系统为例)—thread成员函数

这篇具有很好参考价值的文章主要介绍了C++ thread编程(Linux系统为例)—thread成员函数。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

c++ 11 之后有了标准的线程库:std::thread。
参考thread库的使用

成员函数

构造函数

thread的构造函数有下面四个重载

默认构造函数

thread() noexcept

初始化构造函数

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

该函数使用可变参数模板来构造一个线程对象,用来代表一个新的可join的执行线程。这个执行线程通过可变参数传入线程函数对象fn,以及函数的参数列表(可以简单理解为通过传值的方式将参数传给该构造函数)

拷贝构造函数

thread (const thread&) = delete;

线程不支持拷贝构造

移动构造

thread(thread&&x) noexcept;

转移参数x所代表的可执行指令的所有权,而不会影响线程的执行,转移后,参数x不再代表任何执行线程。

析构函数

析构函数用于销毁线程,如果这个线程是可以join的,那么析构函数会调用terminate()函数来终止线程。在thread对象被销毁之前应该尽可能将其join或者detach,以防止执行线程因为对象销毁而终止。

#include<iostream>
#include<thread>
#include<unistd.h>
using namespace std;
void printtHelloWorld(){
    while(true){
        cout<<"hello world"<<endl;
        sleep(1);
    }
}

int main(){
    thread t1(printtHelloWorld);
    sleep(3);
    t1.~thread();
    return 0;
}

C++ thread编程(Linux系统为例)—thread成员函数

operator=

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

thread对象不允许拷贝构造,同样的对于赋值操作符的重载实质是移动赋值。


#include<iostream>
#include<thread>
using namespace std;
void printHelloWorld(){
    cout<<"Hello World!"<<endl;
}
int main(){
    thread t1;
    t1 = thread(printHelloWorld);
    t1.join();
    return 0;
}

编译g++ test.cpp -std=c++11 -lpthread - o test
C++ thread编程(Linux系统为例)—thread成员函数

joinable

如果thread对象代表了一个执行线程,那么可以joinable。
C++中有几种情况不能joinable

  • 默认构造
  • 执行过move操作
  • 执行过join或者detach
#include<iostream>
#include<thread>
using namespace std;
void printHelloWorld(){
    cout<<"Hello World!"<<endl;
}
int main(){
    thread t1;
    if(!t1.joinable()){
        cout<<"Thread is not joinable! (default constructor)"<<endl;
    }
    t1 = thread(printHelloWorld);
    if(t1.joinable()){
        cout<<"Thread is joinable! (represents a thread of execution)"<<endl;
        t1.join();
        if(!t1.joinable()){
            cout<<"Thread is not joinable! (after call join())"<<endl;
        }
    }
    thread t3;
    thread t2(printHelloWorld);
    t3 = move(t2);
    if(!t2.joinable()){
        cout<<"Thread is not joinable! (after move)"<<endl;
    }
    t3.join();
    return 0;
}

Thread is not joinable! (default constructor)
Thread is joinable! (represents a thread of execution)
Hello World!
Thread is not joinable! (after call join())
Thread is not joinable! (after move)
Hello World!

join

线程执行完毕后函数返回,join函数可以用来阻塞调用此函数的线程,调用这个函数之后,线程对象将变成非joinable并且可以被安全销毁。

#include<iostream>
#include<thread>
#include<unistd.h>
using namespace std;
void pauseThread(int n){
    sleep(n);
    std::cout<<"pause of "<<n<<" seconds ended"<<std::endl;
}
int main(){
    cout<<"spawing 3 threads..."<<endl;
    std::thread t1(pauseThread,1);
    std::thread t2(pauseThread,2);
    std::thread t3(pauseThread,3);
    cout<<"Done spawning threads. Now wait for them to join: "<<endl;
    t1.join();
    t2.join();
    t3.join();
    cout<<"All threads joined!"<<endl;
    return 0;
}

C++ thread编程(Linux系统为例)—thread成员函数

detach

这个函数会将执行线程与调用线程分离,允许它们彼此独立运行,任意一个线程结束之后会释放拥有的资源。调用之后,线程对象会变成非joinable并且可以安全销毁。

#include<iostream>
#include<thread>
#include<unistd.h>
using namespace std;
void pauseThread(int n){
    this_thread::sleep_for(chrono::seconds(n));
    std::cout<<"pause of "<<n<<" seconds ended"<<std::endl;
}
int main(){
    cout<<"spawing 3 threads..."<<endl;
    std::thread (pauseThread,1).detach();
    std::thread (pauseThread,2).detach();
    std::thread (pauseThread,3).detach();
    cout<<"Done spawning threads. (the main thread will now pause for 5 seconds)"<<endl;
    pauseThread(5);
    return 0;
}

C++ thread编程(Linux系统为例)—thread成员函数

创建方法

一般函数创建

#include<iostream>
#include<thread>
#include<unistd.h>
using namespace std;
void printtHelloWorld(){
    while(true){
        cout<<"hello world"<<endl;
        sleep(1);
    }
}

int main(){
    thread t1(printtHelloWorld);
    sleep(3);
    t1.~thread();
    return 0;
}

类的成员函数创建

类外创建

#include<iostream>
#include<thread>
#include<unistd.h>
using namespace std;
class SaySomething{
public:
    void sayHello(){
        cout<<"Hello World!\n";
    }
    void saySomething(string str){
        cout<<str;
    }
    static void sayHelloStatic(){
        cout<<"Hello static!\n";
    }
};
int main(){
    SaySomething sh;
    thread t(&SaySomething::sayHello,&sh);                      //需要传入对象的地址
    thread t1(&SaySomething::saySomething,&sh,"Hello cpp!\n");  //需要传入对象的地址和参数
    thread t2(&SaySomething::sayHelloStatic);                   //静态成员函数不需要传入对象的地址,因为静态成员函数不属于对象
    t.join();
    t1.join();
    t2.join();
    return 0;
}

C++ thread编程(Linux系统为例)—thread成员函数

类内创建thread对象

#include<iostream>
#include<thread>
#include<unistd.h>
using namespace std;
class SaySomething{
private:
    thread workThread;
    void sayHello(){
        cout<<"Hello world!\n";
    }
public:
    SaySomething(){
        workThread=thread(&SaySomething::sayHello,this);  //需要传入对象的地址
    }
    ~SaySomething(){
        workThread.join();                                //等待线程结束,防止主线程退出时子线程被强制结束
    }
};
int main(){
    SaySomething saySomething; //Hello World!
    return 0;
}

使用函数类创建

使用函数类创建

重载operator()来实现类似于函数的操作

#include<iostream>
#include<thread>
#include<unistd.h>
using namespace std;
class FunctionObject{
public:
    void operator()(string str){
        cout << str << endl;
    }
    void operator()(){
        cout << "Hello World!\n";
    }
};
int main(){
    FunctionObject fo;
    thread t(fo);                       //无参数版本
    thread t1(fo, "Hello parameter!\n");    //有参数版本
    t.join();
    t1.join();
    return 0;
}

C++ thread编程(Linux系统为例)—thread成员函数

lambda函数创建

#include<bits/stdc++.h>
using namespace std;
int main(){
    thread t([]{
        cout << "Hello from thread!" << endl;
    });
    t.join();
    return 0;
}

function类创建

function类实例化的对象可以包装以下任何类型的可调用对象:函数、函数指针、指向成员函数的指针或者任何类型的函数对象(即,其类定义 operator()的对象,包括闭包)

#include<iostream>
#include<thread>
#include<unistd.h>
#include<functional>
using namespace std;
void add(int a,int b){
    cout<<"Sum is: "<<a+b<<"\n";
}
int main(){
    function<void(int,int)> f=add;                          //function类包装add函数
    function<void(void)> f1 = bind(add,15,25);              //function包装一个闭包
    function<void(void)> f2 = [](){cout<<"from lambda"<<endl;};//function类包装一个lambda函数
    thread t(f,10,20); 
    sleep(1);                                     //需要传递参数,输出Sum is: 30
    thread t1(f1);      
    sleep(1);                                    //无需传参,输出Sum is: 40
    thread t2(f2);                                          //无需传参
    t.join();
    t1.join();
    t2.join();
    return 0;
}

C++ thread编程(Linux系统为例)—thread成员函数

bind的返回值创建

bind可以将函数和参数绑定为一个函数对象。

#include<iostream>
#include<thread>
#include<unistd.h>
#include<functional>
using namespace std;
void add(int a,int b){
    cout<<"Sum is: "<<a+b<<"\n";
}
int main(){
    auto f1 = bind(add,5,10);
    f1();                           // Sum is: 15
    auto f2 = bind(add,placeholders::_1,placeholders::_2);
    f2(10,20);                      // Sum is: 30
    thread t1(f1);
    thread t2(f2,20,30);
    t1.join();                      // Sum is: 15 来自线程的执行结果
    t2.join();                      // Sum is: 50 来自线程的执行结果
    return 0;
}

C++ thread编程(Linux系统为例)—thread成员函数文章来源地址https://www.toymoban.com/news/detail-454104.html

到了这里,关于C++ thread编程(Linux系统为例)—thread成员函数的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C++ 学习 ::【基础篇:13】:C++ 类的基本成员函数:类类型成员的初始化与构造函数问题

    本系列 C++ 相关文章 仅为笔者学习笔记记录,用自己的理解记录学习!C++ 学习系列将分为三个阶段: 基础篇、STL 篇、高阶数据结构与算法篇 ,相关重点内容如下: 基础篇 : 类与对象 (涉及C++的三大特性等); STL 篇 : 学习使用 C++ 提供的 STL 相关库 ; 高阶数据结构与算

    2024年02月08日
    浏览(48)
  • 再探C++——默认成员函数

    目录 一、构造函数 二、析构函数 三、赋值运算符 四、拷贝构造 如果一个类中没有成员,我们称为空类。空类,也存在6个默认的类成员函数。 默认成员函数:用户不显示地写,编译器会 默认生成 的函数叫做默认成员函数。 6个默认成员函数: 构造函数:完成对象初始化 

    2024年02月14日
    浏览(27)
  • [C++]六大默认成员函数详解

    ☃️个人主页:fighting小泽 🌸作者简介:目前正在学习C++和Linux 🌼博客专栏:C++入门 🏵️欢迎关注:评论👊🏻点赞👍🏻留言💪🏻 如果一个类中什么都没有,简称空类。 但它并不是什么都没有,任何类在什么都不写的情况下, 编译器会自动生成以下6个默认成员函数。

    2024年02月04日
    浏览(32)
  • 深入理解c++特殊成员函数

    在c++中,特殊成员函数有下面6个: 构造函数 析构函数 复制构造函数(拷贝构造函数) 赋值运算符(拷贝运算符) 移动构造函数(c++11引入) 移动运算符(c++11引入) 以Widget类为例,其特殊成员函数的签名如下所示: 每个方法都有哪些作用,又都有哪些注意点? 本文将针对这些方法,

    2024年02月11日
    浏览(34)
  • C++类的默认成员函数

    什么是默认函数? 默认函数就是当你使用这个类对象时,这个类会自动调用的函数C++中有六个默认成员函数,并且作用各不相同,下面我们来一一进行介绍 什么是构造函数?构造函数是干什么的? 什么是析构函数?析构函数是干什么的? 我们以栈为例,每一次我们在使用栈的时

    2024年02月02日
    浏览(33)
  • C++类和对象-C++对象模型和this指针->成员变量和成员函数分开存储、this指针概念、空指针访问成员函数、const修饰成员函数

    #includeiostream using namespace std; //成员变量 和 成员函数 分开储存的 class Person { public:     Person() {         mA = 0;     }     //非静态成员变量占对象空间     int mA;     //静态成员变量不占对象空间     static int mB;     //函数也不占对象空间,所有函数共享一个函数实例

    2024年02月20日
    浏览(35)
  • c++静态变量成员函数和全局函数的区别

    静态成员函数和全局函数在某些方面是相似的,但它们有一些关键的区别。 静态成员函数是与类相关联的函数,但它们不依赖于特定的类实例 。这意味着它们可以 在没有类实例的情况下被调用 ,并且没有隐含的this指针。静态成员函数可以通过类名直接调用,例如: 静态成

    2024年02月08日
    浏览(48)
  • C++编译静态成员函数报错: “osgGA::DriveManipulator::setEye”: 非静态成员函数的非法调用

    来看代码 但是会报错,说引用错误。 这是因为把computePosition函数定义为 static 引起的。 解决办法: computePosition函数定义为 static 不能更改了(我的代码需求,static必须存在),所以要在它内部使用,需要把其它函数也改成静态的。 更改如下: 关于.cpp文件那两行应该放在哪

    2024年02月09日
    浏览(38)
  • C++ list类成员函数介绍

    目录 🤔list模板介绍: 🤔特点: 🤔list内存结构图解: 🤔 list的成员函数: 😊list构造函数: 🔍代码示例: 🔍运行结果: 😊list赋值函数: 🔍代码实例: 🔍运行结果: 😊list判断函数: 🔍代码实例: 运行结果: 😊 list的删除和插入 🔍代码实例: 运行结果: 😊

    2024年02月07日
    浏览(30)
  • 【C++】类的默认成员函数(下)

    🔥 博客主页 : 小羊失眠啦. 🎥 系列专栏 : 《C语言》 《数据结构》 《C++》 《Linux》 《Cpolar》 ❤️ 感谢大家点赞👍收藏⭐评论✍️ 本章主要内容为认识与学习C++非常重要的概念—— 运算符重载 。通过 日期类 的实现,逐步学习各个运算符重载的实现方法即含义。6个默

    2024年03月18日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包