(2)线程管理

一上来就用一段代码来开启这节课...

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

void function_1()
{
    cout << "Hello world!" << endl;
}


int main(int argc, char** argv)
{
    std::thread t1(function_1);
    for(int i=0;i<100;++i)
    {
        cout << "from main:" << i << endl;
    }
    t1.join();
    return 0;
}

编译的指令和(1)介绍的一样,之后就不再提及了.而此时线程启动运行的时间不一定,可能会在主线程不同的输出过程中执行.而这里如果,在主线程中的for语句出现异常的话,那么t1对象则会被销毁,也就是没有机会完成它自己的使命了,那该怎么办呢?哦,很简单,那就捕捉异常罗,哈哈.

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

void function_1()
{
    cout << "Hello world!" << endl;
}


int main(int argc, char** argv)
{
    std::thread t1(function_1);
    try {
        for(int i=0;i<100;++i)
        {
            cout << "from main:" << i << endl;
        }
    }
    catch(...)//用于捕捉所有异常
    {
        t1.join();
        throw;//抛出异常
    }
    t1.join();
    return 0;
}

接下来,就介绍到函数并不是构造线程的唯一方式,这里还可以用任何可调用对象来进行构造线程.这里先构造一个类来进行构造线程.

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

void function_1()
{
    cout << "Hello world!" << endl;
}

class Factor {
public:
    void operator()(){
        for(int i=0;i<100;++i)
            cout << "from t1: " << i << endl;
    }
};

int main(int argc, char** argv)
{
    Factor fct;
    std::thread t1(fct);
    try {
        for(int i=0;i<100;++i)
        {
            cout << "from main:" << i << endl;
        }
    }
    catch(...)
    {
        t1.join();
        throw;
    }
    t1.join();
    return 0;
}

这里两个线程之间的输出没有什么规律,可能每一次运行,输出的顺序都不太一样.

//也可以将
Factor fct;
std::thread t1(fct);
//改成
std::thread t1((Factor()));
//效果一样

然后,就介绍新的东西,也就是在线程构造的时候传入参数,代码如下所示.

#include <thread>
#include <iostream>
#include <string>

using namespace std;

void function_1()
{
    cout << "Hello world!" << endl;
}

class Factor {
public:
    void operator()(string msg){
        for(int i=0;i<100;++i)
            cout << "from t1: " << msg << endl;
    }
};

int main(int argc, char** argv)
{
    string msg = "hello t1 thread!";
    std::thread t1((Factor()),msg);
    try {
        for(int i=0;i<100;++i)
        {
            cout << "from main:" << i << endl;
        }
    }
    catch(...)
    {
        t1.join();
        throw;
    }
    t1.join();
    return 0;
}

哦,听说线程里传参数了,那你试试改改参吧,哈哈.

//注释:在运行这里的代码的时候,视频中可以直接运行,即不用std::ref(),而我则一直出错,所以只能直接上有效代码.视频中如果不用std:ref(msg),则此时还是传参的过程,即不能更改msg的信息.
#include <thread>
#include <iostream>
#include <string>

using namespace std;

void function_1()
{
    cout << "Hello world!" << endl;
}

class Factor {
public:
    void operator()(string& msg){
        cout << "from t1: " << msg << endl;
        msg = "I have changed from t1~";
    }
};

int main(int argc, char** argv)
{
    string msg = "hello t1 thread!";
    std::thread t1((Factor()),std::ref(msg));//注释说的是这个地方
    t1.join();
    cout << "from main:" << msg << endl;
    return 0;
}

上面这个代码其实已经涉及到了共享内存,即msg的共享,会产生数据竞争的问题.接着,介绍另外一种传参方式,既高效,又方便,即std::move(msg),也就是将msg从主线程移动到子线程中,其实还有很多类型只能移动,不能拷贝,例如thread对象.

//举个例子
thread t1((Factor()),std::move(msg));
//thread t2 = t1;//会出错,因为不能拷贝
thread t2 = std::move(t1);//才是正确打开方式
t2.join();//这个地方也不再是t1,因为t1已经为空了

还有就是如果想要查询线程的id,则可以在线程执行代码中使用语句

cout << this_thread::get_id();//显示当前id号
//或者可以用t1.get_id()来查询

标准库提供了函数来查询当前CPU可以最多用多少个线程进行并发编程.

std::thread::hardware_concurrency();

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值