多线程std::thread的使用以及处理线程安全的函数

转载 2017年01月03日 10:39:19

有的时候很多操作如果在Cocos2d-x的主线程中来调用,可能会极大地占用主线程的时间,从而使游戏的不流畅。比如在获取网络文件数据或者在数据比较大的游戏存档时,就需要使用多线程了。


网上的一些教程上是使用pthread来创建新线程的,需要加入lib和头文件,但在Cocos2d-x 3.0中并未发现有pthread的支持文件,后来才发现在C++11中已经拥有了一个更好用的用于线程操作的类std::thread。Cocos2d-x 3.0的版本默认是在vs2012版本,支持C++11的新特性,使用std::thread来创建线程简直方便。

直接调用函数

std::thread t(func);  
带参数的函数

std::thread t(func,param1,param2...);  

类的成员函数(函数类型不需要是静态的)

class MyClass    
{    
    void func1();    
    void func2(int a,string b);    
}    
MyClass myclass;    
std::thread t1(&MyClass::func1,&myclass);     
std::thread t2(&MyClass::func2,&myclass,444,"this is a string");     
t1.detach();    
t2.join();  

detach() 将子线程从主线程里分离,子线程执行完成后会自己释放掉资源。分离后的线程,主线程将对它将没有控制权。

join() 等待子线程执行完之后,主线程才可以继续执行下去,此时主线程会释放掉执行完后的子线程资源。

可以看出使用std::thread来创建线程十分的方便,而且可读性更好了,特别是在传参数这方面。

还有就是线程的互斥量std::mutex

void thread_fun1()    
{    
   _mutex.lock();//加锁    
   ...    
   _mutex.unlock();//解锁    
}    
void thread_fun2()    
{    
    std::lock_guard<std::mutex> lk(_mutex); //线程开始加锁,退出时自动解锁    
    ...    
}  

2.performFunctionInCocosThread()函数

在Cocos2d-x中使用多线程,难免要考虑线程安全的问题。Cocos2d-x 3.0中新加入了一个专门处理线程安全的函数performFunctionInCocosThread()。他是Scheduler类的一个成员函数:

void Scheduler::performFunctionInCocosThread(const std::function<void ()> &function)    
     
/** calls a function on the cocos2d thread. Useful when you need to call a cocos2d function from another thread.   
This function is thread safe.   
@since v3.0   
*/ 

在其他线程中控制主线程去调用一个函数,这个函数会是线程安全的。

具体定义:


void Scheduler::performFunctionInCocosThread(const std::function<void ()> &function)    
{    
    _performMutex.lock();    
     
    _functionsToPerform.push_back(function);    
     
    _performMutex.unlock();    
}  

使用这个函数就能安全的在其他线程中去控制cocos2dx的一些操作了。但是在使用时也要注意一些问题:

1)同步问题 

因为使用performFunctionInCocosThread将参数函数中的代码放到主线程中去运行,所以就无法知道运行完这段代码需要多少时间,可能线程已经运行完毕退出了而那部分代码还没有执行完毕。

可以做一下测试:

void thread_fun()    
{    
    log("new thread create:t_id:0x%x",GetCurrentThreadId());    
     
    Director::getInstance()->getScheduler()->performFunctionInCocosThread([&,this]    
    {    
        for(int i=0;i<=1000;i++){}    
        log("[performFunctionInCocosThread] finished!");    
    });    
     
    log("thread finished:t_id:0x%x",GetCurrentThreadId());    
} 
然后在Cocos2d-x中以这个函数创建一个线程,运行可以看到结果:


可以看出performFunctionInCocosThread中的代码执行完毕在线程退出之后,所以在使用时可能要加入一些值判断代码是否已经运行完毕。


2)互斥问题

如果在线程中要使用互斥,而又要使用performFunctionInCocosThread的话。我认为应该将performFunctionInCocosThread调用放到线程的最后,然后在performFunctionInCocosThread调用函数的末尾使用mutex.unlock(),这样才能确保互斥。


在自己的线程中对精灵的创建等操作可能会没有用,所有performFunctionInCocosThread还是很有用的。


Cocos2d-x的线程学习就到这了。


来源网址:http://blog.csdn.net/oowoodone/article/details/20777447

QT qwebengineview 崩溃

qwebengineview 完美解决 崩溃
  • cammyn
  • cammyn
  • 2016年10月18日 15:18
  • 1153

openal 笔记

下图展示了基本的OpenAL对象以及它们和上下文(context)、设备对象(device objects)之间的关系 初始化OpenAL的时候,至少一个设备要被打开。在这个设备中至少会...

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

#ifndef __HELLOWORLD_SCENE_H__ #define __HELLOWORLD_SCENE_H__ #include "cocos2d.h" #include "cocos-...

C++11 多线程学习----std::thread类的简单使用

C++11标准库会提供类thread(std::thread)。若要运行一个线程,可以创建一个类thread的实体,其初始参数为一个函数对象,以及该函数对象所需要的参数。通过成员函数std::thre...

使用C++11进行多线程归并排序:std::thread

相对于使用pthread来说,c++的标准库对多线程的编程封装的非常好,使用起来有如下几个优势:1:1:可以直接传递参数给函数,而不需要将它封装到一个结构体再转换成为void*传入。22:对于目标函数...

实习点滴 - 跟一个蠢bug学习多线程调试、线程安全和可重入函数

昨天同事帮忙review代码的时候,发现我代码里使用了一个非线程安全的函数localtime,并建议我使用线程安全的localtime_r。于是我查了一下相关资料:time 与 gettimeofda...

多线程原理、线程安全函数和多线程程序需要注意的问题

一、多线程使用情景: 1.用户需要同时得到多个反馈,例如下载过程中进度条改变,读取文件的时候显示结果。 2.提高程序执行性能,提高CPU使用效率,。 多线程的主要是需要处理大量的IO操作或者处理...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:多线程std::thread的使用以及处理线程安全的函数
举报原因:
原因补充:

(最多只允许输入30个字)