在 C++ 中创建和使用线程
Create and use threads in C++
对于大学,我必须编写一个像 space Invaders.
这样的程序
现在我们要为主要的spaceShip
编写"bullet"-Class来发射子弹。
每个项目符号都必须创建自己的线程。线程必须执行 run
方法。
Bullet.hpp
ifndef BULLET_HPP_
define BULLET_HPP_
include "TriangleMesh.hpp"
include <GL/glu.h>
include <GL/glut.h>
include <thread>
include <chrono>
namespace asteroids
{
class Bullet : public TriangleMesh
{
public:
/**
* @brief Contructor. Build a bullet on the given Fighter's
* position. The bullet will move on the
* given axis.
* @param fighter_position Position of the fighter that shoots this bullet
* @param fighter_axis Axis the bullet will move on
*/
Bullet(Vertex<float> fighter_position, Vertex<float> fighter_axis);
~Bullet();
/**
* @brief Moves the bullet until it's lifetime is over.
*/
void run();
/**
* @brief Starts bullet movement
*/
void start();
/*
* @brief Stops bullet movement
*/
void stop();
/**
* @brief Renders the bullet via glutSolidSphere.
*/
void render();
/**
* @brief Returns the status of this bullet.
* @return false, if the bullet's lifetime is over and true otherwise
*/
bool isAlive();
private:
// Lifetime, i.e., how many timesteps the bullet visible
static const int m_lifetime = 9000;
// True, if the bullet's lifetime isn't over yet
bool m_alive;
// Flight direction of the bullet
Vertex<float> m_fighterAxis;
//position of the fighter
Vertex<float> m_fighterPosition;
static void staticRun(Bullet * bullet);
bool isRunning;
/// TODO: ADD TIMING AND THREAD FUNCTIONALITY
void stopThread();
void startThread();
void sleep(int n)
{
std::this_thread::sleep_for(std::chrono::milliseconds(n));
}
};
} // namespace asteroids
#endif /* BULLET_HPP_ */
/**
* Bullet.cpp
*
*/
BULLET.CPP
#include "Bullet.hpp"
using namespace std;
namespace asteroids
{
Bullet::Bullet(Vertex<float> fighter_position, Vertex<float> fighter_axis)
: m_alive(true)
{
// TODO: Implement Ctor logic
m_fighterAxis = fighter_axis;
m_fighterPosition = fighter_position;
m_position = fighter_position;
startThread();
}
void Bullet::stopThread()
{
currentThread->join();
}
//creates a static-member option for starting the thread with an argument.
void Bullet::staticRun(Bullet* bullet)
{
bullet->run();
}
//Logic to create and start a Thread with out static function to execute
void Bullet::startThread()
{
Bullet* bullet = this;
std::thread t1(&Bullet::staticRun, bullet);
currentThread = t1; //Here i wanted to set the pointer equal the existing thread
//But compiler says that i cant convert a thread type to a //pointer type
}
Bullet::~Bullet() {}
bool Bullet::isAlive()
{
return m_alive;
}
void Bullet::stop()
{
m_alive = false;
}
void Bullet::start()
{
if (isAlive())
{
// TODO: Implement thread start logic
startThread();
}
}
void Bullet::run()
{
Vertex<float> move = Vertex<float>(1, 1, 1);
for (int i = 0; i < m_lifetime; i++)
{
m_position = m_fighterAxis + move;
render();
sleep(1000);
//this->sleep(1000);
}
stop();
}
void Bullet::render()
{
// Compute transformation matrix
computeMatrix();
// Push old transformation of the OpenGL matrix stack and
// start rendering the bullet in according to the
// internal transformation matrix
glPushMatrix();
glMultMatrixf(m_transformation);
glutSolidSphere(10, 16, 16);
// Pop transformation matrix of this object
// to restore the previous state of the OpenGL
// matrix stack
glPopMatrix();
}
} // namespace asreroids
现在我的问题是:在单独的方法中创建线程并创建一个保存它的指针是否正确?
或者如果没有线程父class,您将如何实现线程逻辑?
谢谢大家的帮助,如果排版不对请见谅 post 在此表扬一下,这是我第一次 post ^^
拥有太多 "bullet" 个对象并且每个 运行 它都是自己的线程,这将使以后在需要时更难调试....可以做到这一点的一种方法是通过使用 ThreadPool 模式.. 单个线程池不仅可以用于子弹,还可以用于系统中的其他实体......您将拥有所有线程的中央存储库,并且可以在需要时监视它们.. .
https://codereview.stackexchange.com/questions/40536/simple-thread-pool-in-c
Bullet* bullet = this;
std::thread t1(&Bullet::staticRun, bullet);
currentThread = t1;
就上面的代码而言,currentThread 是 class 成员吗?我没有使用太多的 c++11 线程,但是 std::thread t1(&Bullet::静态运行,子弹);一旦方法执行完成就超出范围??
您应该将函数绑定到您要传递的变量,在这种情况下,我建议您将它绑定到您正在创建的实例,然后是函数将接收的参数,通常是您将该函数声明为成员函数,然后将实例绑定到它,然后将它传递给您正在创建的线程。
我们在下面使用互斥锁来保护 running
布尔值免受多线程访问。您应该使用互斥锁来保护可以被多个线程访问的变量。
currentThread.join();
等待线程完成。
#include <thread>
#include <mutex>
#include <chrono>
class Bullet{
public:
void startThread(){
currentThread = std::thread(std::bind(&Bullet::run, this));
}
void run(){
while (isRunning()){
std::this_thread::sleep_for(std::chrono::milliseconds(200));
//Do something.
}
}
void Bullet::stopThread()
{
runMutex.lock();
running = false;
runMutex.unlock();
currentThread.join();
}
bool isRunning(){
bool isRunning = false;
runMutex.lock();
isRunning = running;
runMutex.unlock();
return isRunning;
}
private:
std::thread currentThread;
std::mutex runMutex;
bool running;
};
int main()
{
Bullet bullet;
bullet.startThread();
bullet.stopThread();
return 0; //return.
}
对于大学,我必须编写一个像 space Invaders.
这样的程序现在我们要为主要的spaceShip
编写"bullet"-Class来发射子弹。
每个项目符号都必须创建自己的线程。线程必须执行 run
方法。
Bullet.hpp
ifndef BULLET_HPP_
define BULLET_HPP_
include "TriangleMesh.hpp"
include <GL/glu.h>
include <GL/glut.h>
include <thread>
include <chrono>
namespace asteroids
{
class Bullet : public TriangleMesh
{
public:
/**
* @brief Contructor. Build a bullet on the given Fighter's
* position. The bullet will move on the
* given axis.
* @param fighter_position Position of the fighter that shoots this bullet
* @param fighter_axis Axis the bullet will move on
*/
Bullet(Vertex<float> fighter_position, Vertex<float> fighter_axis);
~Bullet();
/**
* @brief Moves the bullet until it's lifetime is over.
*/
void run();
/**
* @brief Starts bullet movement
*/
void start();
/*
* @brief Stops bullet movement
*/
void stop();
/**
* @brief Renders the bullet via glutSolidSphere.
*/
void render();
/**
* @brief Returns the status of this bullet.
* @return false, if the bullet's lifetime is over and true otherwise
*/
bool isAlive();
private:
// Lifetime, i.e., how many timesteps the bullet visible
static const int m_lifetime = 9000;
// True, if the bullet's lifetime isn't over yet
bool m_alive;
// Flight direction of the bullet
Vertex<float> m_fighterAxis;
//position of the fighter
Vertex<float> m_fighterPosition;
static void staticRun(Bullet * bullet);
bool isRunning;
/// TODO: ADD TIMING AND THREAD FUNCTIONALITY
void stopThread();
void startThread();
void sleep(int n)
{
std::this_thread::sleep_for(std::chrono::milliseconds(n));
}
};
} // namespace asteroids
#endif /* BULLET_HPP_ */
/**
* Bullet.cpp
*
*/
BULLET.CPP
#include "Bullet.hpp"
using namespace std;
namespace asteroids
{
Bullet::Bullet(Vertex<float> fighter_position, Vertex<float> fighter_axis)
: m_alive(true)
{
// TODO: Implement Ctor logic
m_fighterAxis = fighter_axis;
m_fighterPosition = fighter_position;
m_position = fighter_position;
startThread();
}
void Bullet::stopThread()
{
currentThread->join();
}
//creates a static-member option for starting the thread with an argument.
void Bullet::staticRun(Bullet* bullet)
{
bullet->run();
}
//Logic to create and start a Thread with out static function to execute
void Bullet::startThread()
{
Bullet* bullet = this;
std::thread t1(&Bullet::staticRun, bullet);
currentThread = t1; //Here i wanted to set the pointer equal the existing thread
//But compiler says that i cant convert a thread type to a //pointer type
}
Bullet::~Bullet() {}
bool Bullet::isAlive()
{
return m_alive;
}
void Bullet::stop()
{
m_alive = false;
}
void Bullet::start()
{
if (isAlive())
{
// TODO: Implement thread start logic
startThread();
}
}
void Bullet::run()
{
Vertex<float> move = Vertex<float>(1, 1, 1);
for (int i = 0; i < m_lifetime; i++)
{
m_position = m_fighterAxis + move;
render();
sleep(1000);
//this->sleep(1000);
}
stop();
}
void Bullet::render()
{
// Compute transformation matrix
computeMatrix();
// Push old transformation of the OpenGL matrix stack and
// start rendering the bullet in according to the
// internal transformation matrix
glPushMatrix();
glMultMatrixf(m_transformation);
glutSolidSphere(10, 16, 16);
// Pop transformation matrix of this object
// to restore the previous state of the OpenGL
// matrix stack
glPopMatrix();
}
} // namespace asreroids
现在我的问题是:在单独的方法中创建线程并创建一个保存它的指针是否正确?
或者如果没有线程父class,您将如何实现线程逻辑?
谢谢大家的帮助,如果排版不对请见谅 post 在此表扬一下,这是我第一次 post ^^
拥有太多 "bullet" 个对象并且每个 运行 它都是自己的线程,这将使以后在需要时更难调试....可以做到这一点的一种方法是通过使用 ThreadPool 模式.. 单个线程池不仅可以用于子弹,还可以用于系统中的其他实体......您将拥有所有线程的中央存储库,并且可以在需要时监视它们.. .
https://codereview.stackexchange.com/questions/40536/simple-thread-pool-in-c
Bullet* bullet = this;
std::thread t1(&Bullet::staticRun, bullet);
currentThread = t1;
就上面的代码而言,currentThread 是 class 成员吗?我没有使用太多的 c++11 线程,但是 std::thread t1(&Bullet::静态运行,子弹);一旦方法执行完成就超出范围??
您应该将函数绑定到您要传递的变量,在这种情况下,我建议您将它绑定到您正在创建的实例,然后是函数将接收的参数,通常是您将该函数声明为成员函数,然后将实例绑定到它,然后将它传递给您正在创建的线程。
我们在下面使用互斥锁来保护 running
布尔值免受多线程访问。您应该使用互斥锁来保护可以被多个线程访问的变量。
currentThread.join();
等待线程完成。
#include <thread>
#include <mutex>
#include <chrono>
class Bullet{
public:
void startThread(){
currentThread = std::thread(std::bind(&Bullet::run, this));
}
void run(){
while (isRunning()){
std::this_thread::sleep_for(std::chrono::milliseconds(200));
//Do something.
}
}
void Bullet::stopThread()
{
runMutex.lock();
running = false;
runMutex.unlock();
currentThread.join();
}
bool isRunning(){
bool isRunning = false;
runMutex.lock();
isRunning = running;
runMutex.unlock();
return isRunning;
}
private:
std::thread currentThread;
std::mutex runMutex;
bool running;
};
int main()
{
Bullet bullet;
bullet.startThread();
bullet.stopThread();
return 0; //return.
}