I'm making a program that can update the states of objects whilst rendering.
So my first approach was the obvious draw and update in the main while loop, but this problem limited the update state part to the speed of rendering (the computer speed) so this wasn't a good approach.
So I tried to think about the problem and came up with a solution that making a detached thread whose purpose is to update the game. Here is my code of this:
//DEFAULT
#include <iostream>
#include <chrono>
#include <thread>
//SFML
#include <SFML/Graphics.hpp>
void sleep_fnc(bool*);
void update_game(bool*/*, Some objects...*/);
#define cycles_per_milisecond 1000/30
int main() {
bool flag = true;
sf::RenderWindow window(sf::VideoMode(680, 480), "I work!");
std::thread (sleep_fnc, &flag).detach();
std::thread(update_game, &flag/*, Some objects...*/).detach();
if (window.isOpen()) {
window.clear();
//DRAW STUFF HERE
window.display();
}
return 0;
}
void sleep_fnc(bool *flag_ptr) {
while (true)
{
std::this_thread::sleep_for(std::chrono::milliseconds(cycles_per_milisecond));
*flag_ptr = true;
}
}
void update_game(bool *flag_ptr/*, Some objects...*/) {
while (true) {
if (*flag_ptr) {
//Do update stuff
*flag_ptr = false;
}
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
}
After I fiddled around with this code someone else realized that this wasn't such a good solution (thanks to you whomever pointed it out). The reason for this is if one object is being modified by the update loop WHILE the render loop is in its cycle something undefined would probably be the outcome, so I went back and started thinking again.
After thinking I came up with a solution that every class could inherit some universal class that had a boolean whether the object was being used by the draw loop or update loop, if it was in use, one of the loops would wait until the boolean flag indicated that it was ready for use again. It would probably be best if the update loop wasn't the one to wait.
Then it finally hit me that drawing the objects would be useless if they hadn't been updated. I believe that using a timer to test execution time and using that is unreliable, and there must be some other way than limiting the frame rate.
Would this prove that a frame rate higher than the update-rate is useless and is there some other approach that doesn't involve testing the execution time of last cycle and using that?
Related
Hello i'm newbie in C++ specially on STL,
I need to create a function with an infinite loop to calculate and process big data (such as Genetic Algorithm), but i also need keep Ui responsive and update it within (after each round) that infinite loop and start/stop operation manually.
something like this:
bool working = false;
void do_process()
{
while(working)
{
// do some stuff
}
}
void btnStart()
{
working = true;
do_process();
}
void btnEnd()
{
working = false;
}
would you please guide me to a proper solution without any 3rdparty lib, thanks.
and apologies for terrible English.
The code below should get you started. But be careful, implementing a multi-threading application is generally a hard problem also for experienced users. Lot of knowledge is required about memory access synchronization and deadlock analysis. Consider the example below is really essential. For instance, in btnStart and btnStop you should check if a thread is already running. Checking the global bool working may require synchronization. Similarly, checking for null pointer may require synchronization. Bottom line, it is way more complicate than it may seem.
#include <iostream>
#include <utility>
#include <thread>
#include <chrono>
#include <memory>
bool working = false;
std::unique_ptr<std::thread> t;
void do_process()
{
while(working)
{
std::cout << "Hi. I am a secondary thread and I am running.\n";
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
}
void btnStart()
{
working = true;
t.reset(new std::thread(do_process)); // start the thread
}
void btnEnd()
{
working = false; // inform the thread of termination
t->join(); // wait for thread termination
t.reset(NULL);
}
int main()
{
std::cout << "Hi, I am the main thread.\n";
std::cout << "I'll now launch another thread and sleep for a while\n";
btnStart();
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
btnEnd();
std::cout << "What happened while I was slepping?\n";
return 0;
}
I am fairly new also to c++ but i have something that might help.
when i want to run something like an update to my code or to run something external without cramming my original project with code, i like to use ShellExecute to run another c++ program or external program. To use ShellExecute you need #include<windows.h>
For example if i want to update my program, i use #include<fstream>, #include<windows.h>, and #include<string> to check for a value in a file called 'updatereq.txt' (i make it my self). And in my program i run ifstream to check in the file if there is a '1'. If the if statement detects '1' it does this:
void Update(string filename)
{
ShellExecute(NULL,"open",filename.c_str(),NULL,NULL,SW_SHOWNORMAL)
}
This will run with:
HWND set as NULL, Operation set as: "open", File set as string:filenameconstant, Parameters set as NULL, Directory set as NULL(will run in the Directory of originally launching, usually at the main file), and Mode set as SW_SHOWNORMAL which will run it infront of you normally. This is also SW_SHOWMINIMIZED and SW_SHOWMAXIMIZED
Hope this helps!
PS: Remember to mention the file / program name that you are going to run when calling this function
In the following example (an idealized "game") there are two threads. The main thread which updates data and RenderThread which "renders" it to the screen. What I need it those two to be synchronized. I cannot afford to run several update iteration without running a render for every single one of them.
I use a condition_variable to sync those two, so ideally the faster thread will spend some time waiting for the slower. However condition variables don't seem to do the job if one of the threads completes an iteration for a very small amount of time. It seems to quickly reacquire the lock of the mutex before wait in the other thread is able to acquire it. Even though notify_one is called
#include <iostream>
#include <thread>
#include <chrono>
#include <atomic>
#include <functional>
#include <mutex>
#include <condition_variable>
using namespace std;
bool isMultiThreaded = true;
struct RenderThread
{
RenderThread()
{
end = false;
drawing = false;
readyToDraw = false;
}
void Run()
{
while (!end)
{
DoJob();
}
}
void DoJob()
{
unique_lock<mutex> lk(renderReadyMutex);
renderReady.wait(lk, [this](){ return readyToDraw; });
drawing = true;
// RENDER DATA
this_thread::sleep_for(chrono::milliseconds(15)); // simulated render time
cout << "frame " << count << ": " << frame << endl;
++count;
drawing = false;
readyToDraw = false;
lk.unlock();
renderReady.notify_one();
}
atomic<bool> end;
mutex renderReadyMutex;
condition_variable renderReady;
//mutex frame_mutex;
int frame = -10;
int count = 0;
bool readyToDraw;
bool drawing;
};
struct UpdateThread
{
UpdateThread(RenderThread& rt)
: m_rt(rt)
{}
void Run()
{
this_thread::sleep_for(chrono::milliseconds(500));
for (int i = 0; i < 20; ++i)
{
// DO GAME UPDATE
// when this is uncommented everything is fine
// this_thread::sleep_for(chrono::milliseconds(10)); // simulated update time
// PREPARE RENDER THREAD
unique_lock<mutex> lk(m_rt.renderReadyMutex);
m_rt.renderReady.wait(lk, [this](){ return !m_rt.drawing; });
m_rt.readyToDraw = true;
// SUPPLY RENDER THREAD WITH DATA TO RENDER
m_rt.frame = i;
lk.unlock();
m_rt.renderReady.notify_one();
if (!isMultiThreaded)
m_rt.DoJob();
}
m_rt.end = true;
}
RenderThread& m_rt;
};
int main()
{
auto start = chrono::high_resolution_clock::now();
RenderThread rt;
UpdateThread u(rt);
thread* rendering = nullptr;
if (isMultiThreaded)
rendering = new thread(bind(&RenderThread::Run, &rt));
u.Run();
if (rendering)
rendering->join();
auto duration = chrono::high_resolution_clock::now() - start;
cout << "Duration: " << double(chrono::duration_cast<chrono::microseconds>(duration).count())/1000 << endl;
return 0;
}
Here is the source of this small example code, and as you can see even on ideone's run the output is frame 0: 19 (this means that the render thread has completed a single iteration, while the update thread has completed all 20 of its).
If we uncomment line 75 (ie simulate some time for the update loop) everything runs fine. Every update iteration has an associated render iteration.
Is there a way to really truly sync those threads, even if one of them completes an iteration in mere nanoseconds, but also without having a performance penalty if they both take some reasonable amount of milliseconds to complete?
If I understand correctly, you want the 2 threads to work alternately: updater wait until the renderer finish before to iterate again, and the renderer wait until the updater finish before to iterate again. Part of the computation could be parallel, but the number of iteration shall be similar between both.
You need 2 locks:
one for the updating
one for the rendering
Updater:
wait (renderingLk)
update
signal(updaterLk)
Renderer:
wait (updaterLk)
render
signal(renderingLk)
EDITED:
Even if it look simple, there are several problems to solve:
Allowing part of the calculations to be made in parallel: As in the above snippet, update and render will not be parallel but sequential, so there is no benefit to have multi-thread. To a real solution, some the calculation should be made before the wait, and only the copy of the new values need to be between the wait and the signal. Same for rendering: all the render need to be made after the signal, and only getting the value between the wait and the signal.
The implementation need to care also about the initial state: so no rendering is performed before the first update.
The termination of both thread: so no one will stay locked or loop infinitely after the other terminate.
I think a mutex (alone) is not the right tool for the job. You might want to consider using a semaphore (or something similar) instead. What you describe sound a lot like a producer/consumer problem, i.e., one process is allowed to run once everytime another process has finnished a task. Therefore you might also have a look at producer/consumer patterns. For example this series might get you some ideas:
A multi-threaded Producer Consumer with C++11
There a std::mutex is combined with a std::condition_variable to mimic the behavior of a semaphore. An approach that appears quite reasonable. You would probably not count up and down but rather toggle true and false a variable with needs redraw semantics.
For reference:
http://en.cppreference.com/w/cpp/thread/condition_variable
C++0x has no semaphores? How to synchronize threads?
This is because you use a separate drawing variable that is only set when the rendering thread reacquires the mutex after a wait, which may be too late. The problem disappears when the drawing variable is removed and the check for wait in the update thread is replaced with ! m_rt.readyToDraw (which is already set by the update thread and hence not susceptible to the logical race.
Modified code and results
That said, since the threads do not work in parallel, I don't really get the point of having two threads. Unless you should choose to implement double (or even triple) buffering later.
A technique often used in computer graphics is to use a double-buffer. Instead of having the renderer and the producer operate on the same data in memory, each one has its own buffer. This is implemented by using two independent buffers, and switch them when needed. The producer updates one buffer, and when it is done, it switches the buffer and fills the second buffer with the next data. Now, while the producer is processing the second buffer, the renderer works with the first one and displays it.
You could use this technique by letting the renderer lock the swap operation such that the producer may have to wait until rendering is finished.
I'm trying to create C++ program in the sense of embedded hardware programs that work in real time. The main loop in my C++ program uses a delay time of 250milliseconds. It's like:
int main()
{
do{
doSomething();
delay(250);
}while(1)
}
The delay in main loop is crucial for my program to operate.
I need to check something else using 5ms delays.
sideJob()
{
while(1){
checkSomething();
delay(5);
}
}
How do I define the function sideJob to run at the same with the main loop. All in all, I need to get the hang of threading by using, if possible, simple functions. I'm using Linux. Any help will be greately appreaciated.
EDIT: This is what I got so far, But I want to run the sideJob and main thread at the same time.
#include <string>
#include <iostream>
#include <thread>
using namespace std;
//The function we want to make the thread run.
void task1(string msg)
{
cout << "sideJob Running " << msg;
}
int main()
{
// Constructs the new thread and runs it. Does not block execution.
thread t1(task1, "Hello");
//Makes the main thread wait for the new thread to finish execution, therefore blocks its own execution.
t1.join();
while(1){
printf("Continuous Job\n");
}
}
Use different threads in order to do this tasks in parallel.
To learn for more about this, look here.
For an example on StackOverflow, look here.
You can also find plenty of tutorials out there (for example, here).
Suppose I have C++ code such as
#include "myheaderfiles.h"
//..some stuff
//...some more stuff
int main()
{
double milliseconds;
int seconds;
int minutes;
int timelimit=2;
...
...
//...code here that increments
//.....milliseconds,seconds, and minutes
while(minutes <=timelimit)
{
//...do stuff
if(milliseconds>500)
{
//...do stuff
//...every half second
} //end if
} //end while
}//end main
The program will run fine and does what its supposed to do but it will use up 90%+ of my cpu.
It was suggested to me to use usleep() in my while loop ever 100ms or so since I really only care about doing stuff every 500ms anyway. That way, it hog the CPU when its not needed.
So I added it to my while loop like so
while(minutes <=timelimit)
{
//...do stuff
if(milliseconds>500)
{
//...do stuff
//...every half second
} //end if
usleep(100000);
} //end while
It compiles fine, but when I run it, the program will hang right at usleep and never return. I read somewhere that before calling usleep, one needs to flush all buffers, so I flushed all file streams and couts etc etc. Still no luck.
I've searched for 2 days for a solution. I've used sleep() too, with no luck.
I found a few alternatives but they seem complicated and will add a lot of code to my program that I dont really fully understand which will complicate it and make it messy, plus it might not work.
I never really put too much thought in my while() loops before because most of the programs I wrote were for microcontrollers or FPGAs which is no problem to hog the processor.
If anyone can help.... any resources, links,books? Thanks.
Your approach somewhat comes from the wrong end. A program should consume 90-100% CPU as long as it has something useful to do (and it should block otherwise, consuming zero CPU).
Sleeping in between will cause execution being longer for no good reason, and consume more energy than just doing the work as fast as possible (at 100% CPU) and then completely blocking until more work is available or until some other significant thing (e.g. half a second has passed, if that matters for you) happens.
With that in mind, structure your program in a way conceptually like:
while(blocking_call() != exit_condition)
{
while(have_work)
do_work();
}
Also, do not sleep during execution, but use timers (e.g. setitimer) to do something at regular intervals. Not only will this be more efficient, but also a lot more precise and reliable.
How exactly you implement this depends on how portable you want your software to be. Under Ubuntu/Linux, you can for example use APIs such as epoll_wait with eventfd rather than writing a signal handler for the timer.
This code works as expected for me (running on OSX though).
#include <unistd.h>
#include <iostream>
int main() {
std::cout << "hello" << std::endl;
int i = 0;
while(i < 10) {
++i;
usleep(100000);
std::cout << "i = " << i << std::endl;
}
std::cout << "bye" << std::endl;
return 0;
}
There is a logical issue or maybe you're making multiple counters? Since you said you've done microcontrollers, I assume you're trying to use clock-cycles as a method of counting while calling the system timers? Also, what has me questioning is if you're recommended to use usleep(x), why are you using double for millisecond? usleep(1) is 1 microsecond == 1000 milliseconds. The sleep(x) is a counter per x second, so the system will suspend it's current task for x amount of seconds.
#include <iostream>
#include <unistd.h>
using namespace std;
#define MILLISECOND 1000
#define SECOND 1000*MILLISECOND
int main(int argc, char *argv[]){
int time = 20;
int sec_counter = 0;
do{
cout<<sec_counter<<" second"<<endl;
usleep(SECOND);
sec_counter++;
} while(sec_counter<time+1);
return 0;
}
If you wanted to use 500ms then replace usleep(SECOND) with usleep(500*MILLISECOND).
I suggest you use a debugger and step through your code to see what's happening.
I'm making a text based game using the Curses library. There is a part of the game where the player enters an "arena". When inside of the arena the program needs to run a loop(1) that allows the player to move, and it also needs to run a loop(2) that moves the enemies around. Loop(2) needs to be delayed using Sleep so that the enemies move slower than the player. In researching this question I've come across something called multi-threading. I'm not sure that I need to learn this in order to get the results I want. I need to have one of these functions loop slower than the other.
While ( true )
{
movePlayer(player_xy);
arena.moveEnemies();
}
The structure of a simple game will update the positions before rendering every frame.
Here's a simplified example that should suit your needs. For some information visit gamedev.net, there you'll find loads of tutorials and guides for your game.
Pseudocode below
MainLoop()
{
// Get Keyboard Input
...
// Game Logic Impl
...
// Update Positions
UpdatePlayerPosition();
for each ai
UpdateAiPosition();
// Check for sound triggers
ProcessSoundTriggers();
// Draw the scene if needed, you can skip some to limit the FPS
DrawScene();
// Flip the buffers if needed ...
DoubleBufferFlip();
}
You shouldn't need to use multithreading for this. One approach you can use is to calculate the amount of time that has elapsed between the each calling of the main loop and use that to update the position of the players. You can also check for user input and use that to update the user's position. You can multiply the elapsed time by different constants to control the relative rates of movement. A more detailed explanation of the game loop can be found here: http://www.koonsolo.com/news/dewitters-gameloop/
use stl library header file <thread>
you can define loops in two functions
For Example:
#include<chrono>
#include<thread>
void fun1(){
while(/*condition*/){
//statments
std::this_thread::sleep_for (std::chrono::seconds(1));
}
}
void fun2(int y){
while(/*codition*/){
//statments
std::this_thread::sleep_for (std::chrono::seconds(2));
}
}
void main(){
std::thread th1(fun1);
std::thread th2(fun2,5);
//now both thread are running concurrently
}
For more details refer to link:
http://www.cplusplus.com/reference/thread/thread/
If you'd like to avoid multi-threading you can run a loop at high frequency and have the player able to move every X loops, while the enemies can only move every Y loops. In that way you can vary the player:enemy movement speed ratio and you can set offsets so that different enemies move at different times (i.e. during a different cycle of the loop).
Something like this (pseudocode):
int loop_counter = 0;
while(doing_battle)
{
if (loop_counter is a multiple of X)
{
Move player;
}
if (loop_counter is a multiple of Y)
{
Move evenmy_0;
}
if ((loop_counter + offset_1) is a multiple of Y)
{
Move enemy_1; // This enemy will move at a different time from enemy_0
}
loop_counter++;
delay(); // Will vary based on how quickly things need to move and how long your loop takes to complete
}