I have a text file full of information on where to place tiles in a game i'm making, the fastest way to access this information is with a for loop. But whenever i use the for loop to get through all the information it freezes the program for about 12 seconds, in those 12 i cant move the window, nothing on the renderer updates/is drawn, and then when i click on the window it breaks and says "window name (Not Responding)". I tried using a while loop but it still does the same thing.
How can i loop through bigger numbers (there are about 4,000 tiles in the level) without the program freezing/hanging on me? I'm just using SDL 2, no OpenGL involved.
int tiles = 4000;
int x[4000];
int y[4000];
tile obj[4000];
for(int i = 0; i < tiles; i++)
{
x[i] = txt.x;
y[i] = txt.y;
obj[i].Load(x[i], y[i]);
obj[i].Add();
SDL_RenderClear(ren);
LoadScreen();
SDL_RenderPresent(ren);
}
Thanks.
You need to create another thread.
It's good idea to wait for all data to load before starting game, so during load, you don't need to render anything. Even with this approach, it is better to use another thread and don't keep "UI Thread" busy. During load time your UI would be mostly disabled except a cancel button that will stop loading thread.
#include <process.h>
bool bReady;
void LoadTiles(void* pArg)
{
// Load Data here
*((int*)pArg) = 0;
///////////////////
bReady = true;
}
void main()
{
btnStart.SetEnabled(false);
bReady = false;
int iTarget;
uintptr_t hLoadingThread = _beginthread(LoadTiles, 0, &iTarget);
while (true) // usually you pick a message here
{
if (bReady)
btnStart.SetEnabled(true);
}
}
This is just a very simple example, multi-threading needs a lot of work and study!
Related
Suppose I have a complex C++ application that I need to debug with a lot of variables. I wanna avoid using std::cout and printf approaches (below there's an explaination why).
In order to explain my issue, I wrote a minimal example using chrono (This program calculates fps of its while cycle over time and increment i_times counter until it reaches 10k):
#include <chrono>
using chrono_hclock = std::chrono::high_resolution_clock;
int main(int argc, char** argv){
bool is_running = true;
float fps;
int i_times=0;
chrono_hclock::time_point start;
chrono_hclock::time_point end;
while(is_running){
start = chrono_hclock::now();
// Some code execution
end = chrono_hclock::now();
fps=(float)1e9/(float)std::chrono::duration_cast<std::chrono::nanoseconds>(end-start).count());
if(++i_times==10000) is_running=false;
}
return 0;
}
I would like to debug this program and watch for fps and i_times variables continuosly over time, without stopping execution.
Of course I can simply use std::cout, printf or other means to output variables values redirecting them to stdout or a file while debugging and those are OK for simple types, but I have multiple variables which data type are struct-based and it would be creepy, time expensive and code bloating to write instructions to print each one of them. Also my application is a realtime video/audio H.264 encoder streaming with RTSP protocol and stopping at breakpoints means visualizing artifacts in my other decoder application because the encoder can't keep up with the decoder (because the encoder hit a breakpoint).
How can I solve this issue?
Thanks and regards!
The IDE I'm currently using for developing is Visual Studio 2019 Community.
I'm using the Local Windows Debugger.
I'm open to using alternative open source IDEs like VSCode or alternative debugging methods to solve this problem and/or to not be confinated into using a specific IDE.
To watch for specific multiple variables in VS I use the built-in Watch Window. While debugging with LWD, I add manually variables by right-clicking them in my source code and click Add Watch. Then those are showed in the Watch Window (Debug-Windows-Watch-Watch 1):
However I can only watch this window contents once I hit a breakpoint I set inside the while cycle, thus blocking execution, so that doesn't solve my issue.
You can use nonblocking breakpoint. First add the breakpoint. Then click on breakpoint settings or right click and select action.
Now you add a message like any string that is suggestive for you. And in brackets include the values to show, for instance
value of y is {y} and value of x is {x}
In the image is shown the value of i when it hits the breakpoint. Check the "Continue code execution" so breakpoint will not block execution. The shape of your breakpoint will change to red diagonal square. You can add also specific conditions if you click the Conditions checkbox.
Now while debugging all these debug messages will be shown in the output window:
In the above image it is showing the following message:
the value of i is {i}
By checking the "Conditions" you can add specific conditions, for instance i%100==0 and it will show the message only if i is divisible by 100.
This time your breakpoint will be marked with a + sign, meaning it has condition. Now while debugging there will be shown the i only when divisible by 100, so you can restrict the output to some more meaningful cases
The strict answer is "no" but...
I think I understand what you're trying to accomplish. This could be done by dumping the watched variables into to shared memory which is read by 2nd process. A watch and a break point in the 2nd would allow you to see the values in Visual Studio without interrupting the original application.
A few caveats:
UAC must be admin on both sides to open the memory handle
This wouldn't work with pointers as the 2nd program only has access to the shared memory
Windows anti-virus went nuts for the first few times I
ran this but eventually calmed down
Worker application:
#include <stdio.h>
#include <conio.h>
#include <tchar.h>
#include <windows.h>
#include <chrono>
#include <thread>
PCWSTR SHARED_MEMORY_NAME = L"Global\\WatchMemory";
struct watch_collection // Container for everything we want to watch
{
int i;
int j;
int k;
};
using chrono_hclock = std::chrono::high_resolution_clock;
int main(int argc, char** argv)
{
bool is_running = true;
float fps;
int i_times = 0;
chrono_hclock::time_point start;
chrono_hclock::time_point end;
HANDLE map_file;
void* shared_buffer;
// Set up the shared memory space
map_file = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(watch_collection), SHARED_MEMORY_NAME);
if (map_file == NULL)
{
return 1; // Didn't work, bail. Check UAC level!
}
shared_buffer = MapViewOfFile(map_file, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(watch_collection));
if (shared_buffer == NULL)
{
CloseHandle(map_file); // Didn't work, clean up the file handle and bail.
return 1;
}
// Do some stuff
while (is_running) {
start = chrono_hclock::now();
for (int i = 0; i < 10000; i++)
{
for (int j = 0; j < 10000; j++)
{
for (int k = 0; k < 10000; k++) {
watch_collection watches { i = i, j = j, k = k };
CopyMemory(shared_buffer, (void*)&watches, (sizeof(watch_collection))); // Copy the watches to the shared memory space
// Do more things...
}
}
}
end = chrono_hclock::now();
fps = (float)1e9 / (float)std::chrono::duration_cast<std::chrono::nanoseconds>(end - start).count();
if (++i_times == 1000000) is_running = false;
}
// Clean up the shared memory buffer and handle
UnmapViewOfFile(shared_buffer);
CloseHandle(map_file);
return 0;
}
Watcher application:
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <tchar.h>
#pragma comment(lib, "user32.lib")
PCWSTR SHARED_MEMORY_NAME = L"Global\\WatchMemory";
struct watch_collection // Container for everything we want to watch
{
int i;
int j;
int k;
};
int main()
{
HANDLE map_file;
void* shared_buffer;
bool is_running = true;
watch_collection watches; // Put a watch on watches
// Connect to the shared memory
map_file = OpenFileMapping(FILE_MAP_ALL_ACCESS, FALSE, SHARED_MEMORY_NAME);
if (map_file == NULL)
{
return 1; // Couldn't open the handle, bail. Check UAC level!
}
shared_buffer = MapViewOfFile(map_file, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(watch_collection));
if (shared_buffer == NULL)
{
CloseHandle(map_file);
return 1;
}
// Loop forever
while (is_running)
{
CopyMemory((void*)&watches, shared_buffer, (sizeof(watch_collection)));
} // Breakpoint here
UnmapViewOfFile(shared_buffer);
CloseHandle(map_file);
return 0;
}
I have a Visual Studio project that worked fine until I tried to implement multithreading. The project acquires images from a GigE camera, and after acquiring 10 images, a video is made from the acquired images.
The program flow was such that the program didn't acquire images when it was making the video. I wanted to change this, so I created another thread that makes the videos from the images. What I wanted is that the program will acquire images continuously, after 10 images are acquired, another thread runs in parallel that will make the video. This will continue until I stop the program, 10 images are acquired, video from these 10 images is made in parallel while the next 10 images are acquired and so on.
I haven't created threads before so I followed the tutorial on this website. Similar to the website, I created a thread for the function that saves the video. The function that creates the video takes the 10 images as a vector argument. I execute join on this thread just before the line where my main function terminates.
For clarity, here's pseudo-code for what I've implemented:
#include ...
#include <thread>
using namespace std;
thread threads[1];
vector<Image> images;
void thread_method(vector<Image> & images){
// Save vector of images to video
// Clear the vector of images
}
int main(int argc, char* argv[]){
// Some stuff
while(TRUE)
{
for (int i = 0; i < 10; i++)
{
//Acquire Image
//Put image pointer in images vector named images
}
threads[0] = thread(thread_method, images)
}
// stuff
threads[0].join();
cout << endl << "Done! Press Enter to exit..." << endl;
getchar();
return 0;
}
When I run the project now, a message pops up saying that the Project.exe has triggered a breakpoint. The project breaks in report_runtime_error.cpp in static bool __cdecl issue_debug_notification(wchar_t const* const message) throw().
I'm printing some cout messages on the console to help me understand what's going on. What happens is that the program acquires 10 images, then the thread for saving the video starts running. As there are 10 images, 10 images have to be appended to the video. The message that says Project.exe has triggered a breakpoint pops up after the second time 10 images are acquired, at this point the parallel thread has only appended 6 images from the first acquired set of images to the video.
The output contains multiple lines of thread XXXX has exited with code 0, after that the output says
Debug Error!
Program: ...Path\Program.exe
abort() has been called
(Press Retry to debug the application)
Program.exe has triggered a breakpoint.
I can't explain all this in a comment. I'm dropping this here because it looks like OP is heading in some bad directions and I'd like to head him off before the cliff. Caleth has caught the big bang and provided a solution for avoiding it, but that bang is only a symptom of OP's and the solution with detach is somewhat questionable.
using namespace std;
Why is "using namespace std" considered bad practice?
thread threads[1];
An array 1 is pretty much pointless. If we don't know how many threads there will be, use a vector. Plus there is no good reason for this to be a global variable.
vector<Image> images;
Again, no good reason for this to be global and many many reasons for it NOT to be.
void thread_method(vector<Image> & images){
Pass by reference can save you some copying, but A) you can't copy a reference and threads copy the parameters. OK, so use a pointer or std::ref. You can copy those. But you generally don't want to. Problem 1: Multiple threads using the same data? Better be read only or protected from concurrent modification. This includes the thread generating the vector. 2. Is the reference still valid?
// Save vector of images to video
// Clear the vector of images
}
int main(int argc, char* argv[]){
// Some stuff
while(TRUE)
{
for (int i = 0; i < 10; i++)
{
//Acquire Image
//Put image pointer in images vector named images
}
threads[0] = thread(thread_method, images)
Bad for reasons Caleth covered. Plus images keeps growing. The first thread, even if copied, has ten elements. The second has the first ten plus another ten. This is weird, and probably not what OP wants. References or pointers to this vector are fatal. The vector would be resized while other threads were using it, invalidating the old datastore and making it impossible to safely iterate.
}
// stuff
threads[0].join();
Wrong for reasons covered by Caleth
cout << endl << "Done! Press Enter to exit..." << endl;
getchar();
return 0;
}
The solution to joining on the threads is the same as just about every Stack Overflow question that doesn't resolve to "Use a std::string": Use a std::vector.
#include <iostream>
#include <vector>
#include <thread>
void thread_method(std::vector<int> images){
std::cout << images[0] << '\n'; // output something so we can see work being done.
// we may or may not see all of the numbers in order depending on how
// the threads are scheduled.
}
int main() // not using arguments, leave them out.
{
int count = 0; // just to have something to show
// no need for threads to be global.
std::vector<std::thread> threads; // using vector so we can store multiple threads
// Some stuff
while(count < 10) // better-defined terminating condition for testing purposes
{
// every thread gets its own vector. No chance of collisions or duplicated
// effort
std::vector<int> images; // don't have Image, so stubbing it out with int
for (int i = 0; i < 10; i++)
{
images.push_back(count);
}
// create and store thread.
threads.emplace_back(thread_method,std::move(images));
count ++;
}
// stuff
for (std::thread &temp: threads) // wait for all threads to exit
{
temp.join();
}
// std::endl is expensive. It's a linefeed and s stream flush, so save it for
// when you really need to get a message out immediately
std::cout << "\nDone! Press Enter to exit..." << std::endl;
char temp;
std::cin >>temp; // sticking with standard librarly all the way through
return 0;
}
To better explain
threads.emplace_back(thread_method,std::move(images));
this created a thread inside threads (emplace_back) that will call thread_method with a copy of images. Odds are good that the compiler would have recognized that this was the end of the road for this particular instance of images and eliminated the copying, but if not, std::move should give it the hint.
You are overwriting your one thread in the while loop. If it's still running, the program is aborted. You have to join or detach each thread value.
You could instead do
#include // ...
#include <thread>
// pass by value, as it's potentially outliving the loop
void thread_method(std::vector<Image> images){
// Save vector of images to video
}
int main(int argc, char* argv[]){
// Some stuff
while(TRUE)
{
std::vector<Image> images; // new vector each time round
for (int i = 0; i < 10; i++)
{
//Acquire Image
//Put image pointer in images vector named images
}
// std::thread::thread will forward this move
std::thread(thread_method, std::move(images)).detach(); // not join
}
// stuff
// this is somewhat of a lie now, we have to wait for the threads too
std::cout << std::endl << "Done! Press Enter to exit..." << std::endl;
std::getchar();
return 0;
}
I'm developing an application in C++ with a GUI in OpenGL. I have a GUI with a background, some squared textures over the background and some text written next to the textures. When I run the program textures start to flash in blocks of n, and a string is printed on the gui in order to identify which block is flashing (I don't know how to better explain, is the P300Speller paradigm). I'm finding a problem due to flashes because the GUI doesn't update as long as I don't move mouse over the window! Can someone help me?
I'll try to post and explain some code. flashSquare is the function which makes textures flash. I use a boolean vector (showSquare) to indicate if the nth texture has to be normal or flashed (I load different textures) and a stack (flashHelperS) filled with integers which represent the stimulus sequence and the order of the flashing textures.
void flashSquare(int square){
if (firstTime){ // send stimulus command
sendToServer(START_STIMULUS);
fillStackS(); // Fill stack of stimuli
firstTime = false;
pausa = false;
}
if (pausa == false){
cout << " Stack size : " << flashHelperS.size() << endl;
if (!flashHelperS.empty()){ // If the stack is not empty
int tmp = flashHelperS.top(); // select the next texture to flash
flashHelperS.pop(); // and remove it from stack
showSquare[tmp] = !showSquare[tmp]; // change bool of current
// flashing texture
cout << showSquare[tmp] << endl;
if (showSquare[tmp]){
counterSquares[tmp]++;
sendToServer(tmp + 1);
}
square = tmp;
glutPostRedisplay(); // Redisplay to show current texture flashed
if (flashHelperS.size() >= 0) { //If the stack is not empty repeat
glutTimerFunc(interface->getFlashFrequency(), flashSquare, 0);
}
}
else{ // If the stack is empty reset
initCounterSquare();
sendToServer(END_STIMULUS);
pausa = true;
if (interface->getMaxSessions() == currentSession){
sendToServer(END_CALIBRATION);
drawOnScreen(); // Draw a string on the screen
firstTime = true;
}
else currentSession++;
}
}
}
For example if stack has 8 items and maxSessions is 3, it means that glutTimerFunc calls flashSquare 8 times, making all the 8 texture flash, than I send to server END_STIMULUS code and repeat this operation other 2 times (because maxSessions is 3). When server receives END_STIMULUS and it is ready to receive more data it sends a code to my client, RESTART_S. When I receive RESTART_S (stack is empty and currentSession < 3) I call flashSquare again to start a new train of stimuli and flash.
if (idFromClient[0] == RESTART_S) {
sendToServer(FLASH_S);
firstTime = true;
flashSquare(0);
}
When I call flashSquare manually the first time it works, but when I receive from server RESTART_S flashSquare is correctly called, indeed it sends to server START_STIMULS, firstTime = false, pausa = false, and it fills the stack. The execution of program goes on to the print of stack size and I can verify that all variables are correctly assigned (debugger shows that the function is called but it does nothing). The problem is that if I don't move mouse over the window with the textures, even if the window is focused, the execution doesn't go on.
I'm trying to write code where the screen is divided into two windows and one of them is modified by a different thread, but output seems to be very random. Could anyone help? Upper piece of console should be modified by main, and lower by thread k.
#include <stdio.h>
#include <ncurses.h>
#include <unistd.h>
#include <thread>
#define WIDTH 30
#define HEIGHT 10
int startx = 0;
int starty = 0;
void kupa (int score_size, int parent_x, int parent_y)
{
int i = 0;
WINDOW *dupa = newwin(score_size, parent_x, parent_y - score_size, 0);
while(true)
{
i++;
mvwprintw(dupa, 0 , 0, "You chose choice %d with choice string", i);
wrefresh(dupa);
sleep(5);
wclear(dupa);
}
delwin(dupa);
}
int main ()
{
int parent_x, parent_y;
int score_size =10;
int counter =0 ;
initscr();
noecho();
curs_set(FALSE);
getmaxyx(stdscr, parent_y, parent_x);
WINDOW *field = newwin(parent_y - score_size, parent_x, 0, 0);
std::thread k (kupa, score_size, parent_x, parent_y);
while(true) {
mvwprintw(field, 0, counter, "Field");
wrefresh(field);
sleep(5);
wclear(field);
counter++;
}
k.join();
delwin(field);
}
The underlying curses/ncurses library is not thread-safe (see for example What is meant by “thread-safe” code? which discusses the term). In the case of curses, this means that the library's WINDOW structures such as stdscr are global variables which are not guarded by mutexes or other methods. The library also has internal static data which is shared across windows. You can only get reliable results for multithreaded code using one of these strategies:
do all of the window management (including input) within one thread
use mutexes, semaphores or whatever concurrency technique seems best to manage separate threads which "own" separate windows. To succeed here, a thread would have to own the whole screen from the point where the curses library blocks while waiting for input, until it updates the screen and resumes waiting for input. That is harder than it sounds.
ncurses 5.7 and up can be compiled to provide rudimentary support for reentrant code and some threaded applications. To do this, it uses mutexes wrapped around its static data, makes the global variables into "getter" functions, and adds functions which explicitly pass the SCREEN pointer which is implied in many calls. For more detail, see the manual page.
Some of ncurses' test-programs illustrate the threading support (these are programs in the test subdirectory of the sources):
ditto shows use_screen.
test_opaque execises the "getters" for WINDOW properties
rain shows use_window
worm shows use_window
I am not sure what you want to do but this behaviour is quite normal. The thread that is active writes to the window and when the system makes a task switch the other thread writes to the window. Normal behaviour is to use only one thread that writes to the window. Other threads are supposed to do only some work.
Anyway, if you are using more than one thread you have to synchronize them using events, mutexes, queues, semaphores or other methods.
I am developing a simple game in c++, a chase-the-dot style one, where you must click a drawn circle on the display and then it jumps to another random location with every click, but I want to make the game end after 60 seconds or so, write the score to a text file and then upon launching the program read from the text file and store the information into an array and somehow rearrange it to create a high score table.
I think I can figure out the high score and mouse clicking in a certain area myself, but I am completely stuck with creating a possible timer.
Any help appreciated, cheers!
In C++11 there is easy access to timers. For example:
#include <chrono>
#include <iostream>
int main()
{
std::cout << "begin\n";
std::chrono::steady_clock::time_point tend = std::chrono::steady_clock::now()
+ std::chrono::minutes(1);
while (std::chrono::steady_clock::now() < tend)
{
// do your game
}
std::cout << "end\n";
}
Your platform may or may not support <chrono> yet. There is a boost implementation of <chrono>.
Without reference to a particular framework or even the OS this is unanswerable.
In SDL there is SDL_GetTicks() which suits the purpose.
On linux, there is the general purpose clock_gettime or gettimeofday that should work pretty much everywhere (but beware of the details).
Win32 API has several function calls related to this, including Timer callback mechanisms, such as GetTickCount, Timers etc. (article)
Using timers is usually closely related to the meme of 'idle' processing. So you'd want to search for that topic as well (and this is where the message pump comes in, because the message pump decides when (e.g.) WM_IDLE messages get sent; Gtk has a similar concept of Idle hooks and I reckon pretty much every UI framework does)
Usually GUI program has so called "message pump" loop. Check of that timer should be a part of your loop:
while(running)
{
if( current_time() > end_time )
{
// time is over ...
break;
}
if( next_ui_message(msg) )
dispatch(msg);
}
Try this one out:
//Creating Digital Watch in C++
#include<iostream>
#include<Windows.h>
using namespace std;
struct time{
int hr,min,sec;
};
int main()
{
time a;
a.hr = 0;
a.min = 0;
a.sec = 0;
for(int i = 0; i<24; i++)
{
if(a.hr == 23)
{
a.hr = 0;
}
for(int j = 0; j<60; j++)
{
if(a.min == 59)
{
a.min = 0;
}
for(int k = 0; k<60; k++)
{
if(a.sec == 59)
{
a.sec = 0;
}
cout<<a.hr<<" : "<<a.min<<" : "<<a.sec<<endl;
a.sec++;
Sleep(1000);
system("Cls");
}
a.min++;
}
a.hr++;
}
}
See the details at: http://www.programmingtunes.com/creating-timer-c/#sthash.j9WLtng2.dpuf