C++11多线程std::thread的简单使用

转自:http://blog.csdn.net/star530/article/details/24186783

在cocos2dx 2.0时代,我们使用的是pthread库,是一套用户级线程库,被广泛地使用在跨平台应用上。但在cocos2dx 3.0中并未发现有pthread的支持文件,原来c++11中已经拥有了一个更好用的用于线程操作的类std::thread。cocos2dx 3.0的版本默认是在vs2012版本,支持c++11的新特性,使用std::thread来创建线程简直方便。

下面介绍下std::thread的一下简单用法,代码需包含头文件<thread>

bool HelloWorld::init()
{
    if ( !Layer::init() )
    {
        return false;
    }

    std::thread t1(&HelloWorld::myThread,this);//创建一个分支线程,回调到myThread函数里
    t1.join();
//    t1.detach();

    CCLOG("in major thread");//在主线程

    return true;
}

void HelloWorld::myThread()
{
    CCLOG("in my thread");
}

运行结果如下图:

t.join()等待子线程myThread执行完之后,主线程才可以继续执行下去,此时主线程会释放掉执行完后的子线程资源。从上面的图片也可以看出,是先输出"in my thread",再输出"in major thread"。
当然了,如果不想等待子线程,可以在主线程里面执行t1.detach()将子线程从主线程里分离,子线程执行完成后会自己释放掉资源。分离后的线程,主线程将对它没有控制权了。如下:

std::thread t1(&HelloWorld::myThread,this);//创建一个分支线程,回调到myThread函数里
t1.detach();

运行结果如下:

当然了,也可以往线程函数里穿参数,这里用到了bind。下面例子在实例化线程对象的时候,在线程函数myThread后面紧接着传入两个参数。

bool HelloWorld::init()
{
    if ( !Layer::init() )
    {
        return false;
    }

    std::thread t1(&HelloWorld::myThread,this,10,20);//创建一个分支线程,回调到myThread函数里
    t1.join();
//    t1.detach();

    CCLOG("in major thread");//在主线程
    return true;
}

void HelloWorld::myThread(int first,int second)
{
    CCLOG("in my thread,first = %d,second = %d",first,second);
}

输出结果如下图:

实例:

1.售票 孙鑫老师的C++和Java多线程售票也一直让我念念不忘(好吧,我承认我没看过),这里用cocos2d-x3.0和C++11的std::thread实现一个吧。总共有100张诺亚方舟船票,有2个售票点A和B在售票(一张票就一百亿美元吧),当票卖完了就结束了。我们知道当程序一开始进程就会创建一个主线程,所以可以在主线程基础上再创建2个线程A和B,再线程A和B中分别售票,当票数为0的时候,结束线程A和B。

2.多线程售票,代码如下:

//HelloWorld.h
class HelloWorld : public cocos2d::Layer
{
public:
    static cocos2d::Scene* createScene();
    virtual bool init();  

    CREATE_FUNC(HelloWorld);

    void myThreadA();//线程A
    void myThreadB();//线程B

    int tickets;//票数  

};

//.cpp
bool HelloWorld::init()
{
    if ( !Layer::init() )
    {
        return false;
    }

    tickets = 100;//100张票

    std::thread tA(&HelloWorld::myThreadA,this);//创建一个分支线程,回调到myThread函数里
    std::thread tB(&HelloWorld::myThreadB,this);
    tA.detach();
    tB.detach();
//    t1.detach();

    CCLOG("in major thread");//在主线程
    return true;
}

void HelloWorld::myThreadA()
{
    while(true)
    {
        if(tickets>0)
        {
            Sleep(10);
            CCLOG("A Sell %d",tickets--);//输出售票,每次减1
        }
        else {
            break;
        }
    }
}
void HelloWorld::myThreadB()
{
    while(true)
    {
        if (tickets>0)
        {
            Sleep(10);
            CCLOG("B Sell %d",tickets--);
        }
        else
        {
            break;
        }
    }
}

代码很简单,不多说了。我们来看一下输出,会发现有很多喜闻乐见的现象出现,因为每个人每次运行的结果都不一样,所以这里不贴结果了,其中比较有意思的现象是同一张票卖了两次?!
原因不多解释了,时间片的问题,不明白的Google之。如果你觉得不会有这么巧,那么在打印结果前加上这么一句:

Sleep(100);

运行结果如图所示:

3.利用互斥对象同步数据
这个问题主要是因为一个线程执行到一半的时候,时间片的切换导致另一个线程修改了同一个数据,当再次切换会原来线程并继续往下运行的时候,数据由于被修改了导致结果出错。所以我们要做的就是保证这个线程完全执行完,所以对线程加锁是个不错的注意,互斥对象mutex就是这个锁。
3.1、初始化互斥锁

std::mutex mutex;//线程互斥对象

3.2、修改myThreadA与myThreadB的代码,在里面添加互斥锁

void HelloWorld::myThreadA()
{
    while(true)
    {
        mutex.lock();//加锁
        if(tickets>0)
        {
            Sleep(10);
            CCLOG("A Sell %d",tickets--);//输出售票,每次减1
            mutex.unlock();//解锁
        }
        else {
            mutex.unlock();
            break;  

        }
    }
}
void HelloWorld::myThreadB()
{
    while(true)
    {
        mutex.lock();
        if (tickets>0)
        {
            Sleep(10);
            CCLOG("B Sell %d",tickets--);
            mutex.unlock();
        }
        else
        {
            mutex.unlock();
            break;
        }
    }
}

运行结果如下,完美

使用std::mutex有一个要注意的地方:在线程A中std::mutex使用成员函数lock加锁unlock解锁,看起来工作的很好,但这样是不安全的,你得始终记住lock之后一定要unlock,但是如果在它们中间出现了异常或者线程直接退出了unlock就没有执行,因为这个互斥量是独占式的,所以在threadA没有解锁之前,其他使用这个互斥量加锁的线程会一直处于等待状态得不到执行

时间: 2024-10-03 11:44:42

C++11多线程std::thread的简单使用的相关文章

Cocos2dx 3.0 过渡篇(二十七)C++11多线程std::thread的简单使用(下)

本篇接上篇继续讲:上篇传送门:http://blog.csdn.net/star530/article/details/24186783 简单的东西我都说的几乎相同了,想挖点深的差点把自己给填进去. 以下实际演练一下.请同意我參考偶尔E往事的一篇线程的博客, 他用的是pThread.这里我就用std::thread. 1.售票孙鑫老师的C++和Java多线程售票也一直让我念念不忘(好吧,我承认我没看过).这里用cocos2d-x3.0和C++11的std::thread实现一个吧.总共同拥有10

mingw-w64线程模型:posix vs win32(posix允许使用c++11的std:: thread,但要带一个winpthreads,可能需要额外dll)

我正在安装 mingw-w64 on Windows,有两个选项: win32线程和posix线程. 我知道win32线程和pthreads之间的区别,但是我不明白这两个选项之间的区别. 我怀疑如果我选择了posix线程,它将阻止我调用像CreateThread这样的WinAPI函数. 似乎这个选项指定了哪个程序或者库将使用哪个线程 API,但通过什么? 由 GCC,libstdc++或者其他事物? 我发现:什么区别thread_posixs和 thread_win32 gcc Windows

C++11 并发指南一(C++11 多线程初探)(转)

引言 C++11 自2011年发布以来已经快两年了,之前一直没怎么关注,直到最近几个月才看了一些 C++11 的新特性,今后几篇博客我都会写一些关于 C++11 的特性,算是记录一下自己学到的东西吧,和大家共勉. 相信 Linux 程序员都用过 Pthread, 但有了 C++11 的 std::thread 以后,你可以在语言层面编写多线程程序了,直接的好处就是多线程程序的可移植性得到了很大的提高,所以作为一名 C++ 程序员,熟悉 C++11 的多线程编程方式还是很有益处的. 如果你对 C+

std::thread

std::thread为C++11的线程类,使用方法和boost接口一样,非常方便.C++11的std::thread解决了boost::thread中构成参数限制的问题. #include <thread>         // std::thread, std::thread::id, std::this_thread::get_id  #include <chrono>         // std::chrono::seconds void threadfun1(){}vo

c++11多线程记录1 -- std::thread

启动一个线程 话不多说,直接上代码 void func(); int main() { std::thread t(func); //这里就开始启动线程了 return 0; } void func() { std::cout << "Hello, " << std::this_thread::get_id() << std::endl; } 等待子线程结束 有时候开启一个子线程之后,父线程很快运行结束: 如果想要父线程做完自己的工作之后等待子线程运

C++——多线程编程(一)std::thread

(一)与C++11多线程相关的头文件 C++11 新标准中引入了四个头文件来支持多线程编程,他们分别是< atomic> ,< thread>,< mutex>,< condition_variable>和< future>. ?< atomic>:该头文主要声明了两个类, std::atomic 和 std::atomic_flag,另外还声明了一套 C 风格的原子类型和与 C 兼容的原子操作的函数. ?< thread>

[转] c++11并发之std::thread

[转自 https://blog.csdn.net/liuker888/article/details/46848905#] 知识链接: C++11 并发之std::mutex C++11 并发之std::atomic 本文概要: 1.成员类型和成员函数. 2.std::thread 构造函数. 3.异步. 4.多线程传递参数. 5.join.detach. 6.获取CPU核心个数. 7.CPP原子变量与线程安全. 8.lambda与多线程. 9.时间等待相关问题. 10.线程功能拓展. 11.

c++11多线程学习笔记之一 thread基础使用

没啥好讲的  c++11  thread类的基本使用 #include "stdafx.h" #include <iostream> #include <thread> void Func(int n) { for (int i = 0; i < 3; ++i) std::cout << "func " << i << std::endl; } void RefFunc(int& n) { f

C++11 并发指南------std::thread 详解

参考: https://github.com/forhappy/Cplusplus-Concurrency-In-Practice/blob/master/zh/chapter3-Thread/Introduction-to-Thread.md#stdthread-%E8%AF%A6%E8%A7%A3 本节将详细介绍 std::thread 的用法. std::thread 在 <thread> 头文件中声明,因此使用 std::thread 需包含 <thread> 头文件. &