加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

C++11中thread线程的使用

(2017-03-28 20:56:08)
分类: C/Cplusplus
首先需要注意:C++中thread线程操作需要VS2012版本以上才行。否则程序不识别thread头文件。当然可以使用boost中的线程,事实上这两者是一样的。以下是自己学习的笔记。当然里面还有其他的,我会在后续的学习中添加。

注:此处使用“”引用头文件的目的是因为新浪博客的原因,如果使用“《“ ”》”就会消除不显示,所以使用“”引用头文件。

1. 使用函数std::this_thread::get_id()获取当前线程的ID。
#include “iostream”
#include "thread"
int main()
{
        std::cout << std::this_thread::get_id() << std::endl;//显示当前进程的ID。
        return 0;
}

2. 进程的定义
在程序中我们可以直接使用std::thread来定义线程变量。线程变量中传递需要线程运行的函数,比如:

#include “iostream”
#include "thread"
#include "string"
void function()
{
    std::cout << "I Love C/C++" << std::endl;
}
int main()
{
    std::thread t1(function);//开始线程以及参数传递,使用std::ref来进行地址传递
    t1.join();
    return 0;
}
运行结果:
I Love C/C++
请按任意键继续. . .

3. 线程的赋值
使用函数std::move()实现线程的赋值。比如程序

#include “iostream”
#include "thread"
#include "string"
void function()
{
    std::cout << "I Love C/C++" << std::endl;
}
int main()
{
    std::thread t1(function);//开始线程以及参数传递,使用std::ref来进行地址传递
    std::thread t2 = std::move(t1);
    t2.join();
    return 0;
}
运行结果:
I Love C/C++
请按任意键继续. . .

4. 启动的线程是一个类

#include “iostream”
#include "thread"
#include "string"
class Fctor{
public:
    void operator()(std::string msg){
        std::cout << msg << std::endl;
    }
};
int main()
{
    std::string s = "I love C";
    std::thread t1((Fctor()), s);
    t1.join();
    return 0;
}
运行结果:
I love C
请按任意键继续. . .

5. 如何返回线程中的数据
有人认为我们通过地址传递不就可以了吗?那么让我们举一个例子看看。

#include “iostream”
#include "thread"
#include "string"
class Fctor{
public:
    void operator()(std::string &msg){
        std::cout << msg << std::endl;
        msg = "I love C++";
    }
};
int main()
{
    std::string s = "I love C";
    std::thread t1((Fctor()), s);
    t1.join();
    return 0;
}
运行结果:
I love C
I love C
请按任意键继续. . .

通过结果我们发现其实在线程对应的类中我们修改了s的值,但是这个值却没有显示出来。所以这样的方式是不能够获取我们想要的值,我们需要通过函数std::ref()。

6. 获取线程中返回的值
我们通过函数std::ref()来获取线程中的值。我们看一下例子:

#include “iostream”
#include "thread"
#include "string"
class Fctor{
public:
    void operator()(std::string &msg){
        std::cout << msg << std::endl;
        msg = "I love C++";
    }
};
int main()
{
    std::string s = "I love C";
    std::thread t1((Fctor()), std::ref(s));
    t1.join();
    return 0;
}
运行结果:
I love C
I love C++
请按任意键继续. . .

7. 获得某个线程的ID
我们使用函数std::thread::get_id()。

#include “iostream”
#include "thread"
#include "string"
void function()
{
    std::cout << "I Love C/C++" << std::endl;
}
int main()
{
    std::thread t1(function);//开始线程以及参数传递,使用std::ref来进行地址传递
    t1.join();
    std::cout << t1.get_id() << std::endl;
    return 0;
}
运行结果:
I Love C/C++
0
请按任意键继续. . .

8. 线程中mutex中互斥锁的使用。
我们使用mutex需要引入头文件#include “mutex”。
#include "iostream"
#include "thread"
#include "string"
#include "mutex"

std::mutex  mu;

void shared_print(std::string msg, int id)
{
    mu.lock();
    std::cout << msg << id << std::endl;
    mu.unlock();
}

void function()
{
    for (int i = 0; i > -100; --i)
    {
        shared_print("From t1: ", i);
    }
}

int main()
{
    std::thread t1(function);
    for (int i = 0; i < 100; i++)
    {
        shared_print("From t1: ", i);
    }
    t1.join();
    return 0;
}
这个程序就会实现对数据msg和id 的互斥访问,但是这有可能出现问题,如果这两个中的某个数据出现错误,岂不是这段数据就被互斥锁锁定,所以有一个更加安全的互斥锁使用函数:
std::lock_guard guard(mu);

使用方式如下:
#include "iostream"
#include "thread"
#include "string"
#include "mutex"

std::mutex  mu;

void shared_print(std::string msg, int id)
{
    std::lock_guard guard(mu);
    //mu.lock();
    std::cout << msg << id << std::endl;
    //mu.unlock();
}

void function()
{
    for (int i = 0; i > -100; --i)
    {
        shared_print("From t1: ", i);
    }
}

int main()
{
    std::thread t1(function);
    for (int i = 0; i < 100; i++)
    {
        shared_print("From t1: ", i);
    }
    t1.join();
    return 0;
}

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有