Segmentation Fault in SFML After calling sf::Window::close - c++

I'm trying to run an SFML window on a separate thread from main(). Calling sf::Window::close doesn't cause any immediate problems, however at the end of main(), possibly when the UI object is destructed, a segmentation fault error occurs. No segmentation fault occurs if sf::Window::close isn't called.
I'm running a fully updated Debian 10 install.
#include <thread>
#include <SFML/Graphics.hpp>
int main() {
sf::Window window(sf::VideoMode(500,500), "Test");
std::thread th(&sf::Window::close, &window);
th.join();
}

I found the problem. You have to deactivate the window before closing in another thread, like so. I missed this in the documentation initially.
#include <thread>
#include <SFML/Graphics.hpp>
int main() {
sf::Window window(sf::VideoMode(500,500), "Test");
window.setActive(false);
std::thread th(&sf::Window::close, &window);
th.join();
}

Related

Issues using multithreading in SFML for C++ [duplicate]

This question already has an answer here:
SFML fails in multithreading
(1 answer)
Closed 1 year ago.
I am trying to create a separate thread while using the SFML game library. This is a very simplified example.
I'm using WSL and the libsfml-dev library. My issue is that it seems like I cannot perform certain actions using the SFML library on threads other then my main thread. For example, in the code below, I get an error if I click escape. What's supposed to happen is the program simply exits as the loop conditions fail.
If you want to run the code yourself...
to grab the library: apt-get install libsfml-dev
g++ compiler arguments: g++ test.cpp -pthread -lsfml-graphics -lsfml-window -lsfml-system
#include <iostream>
#include <stdio.h>
#include <pthread.h>
#include <SFML/Graphics.hpp>
#include <SFML/System.hpp>
// Create window object
sf::RenderWindow window(sf::VideoMode(800, 800), "");
using namespace std;
void *func(void *threadid) {
// Show thread was created
cout << "New thread was ran." << endl;
while (window.isOpen()) {
// This action kills the program and not in a nice way
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Escape)) {
window.close();
}
}
pthread_exit(NULL);
}
int main() {
// Create new thread
pthread_t threads[1];
int val;
val = pthread_create(&threads[0], NULL, func, (void *)1);
cout << "Main thread was ran." << endl;
// This is here so that the program doesn't exit
while (window.isOpen()) {}
return 0;
}
Error message
It is not uncommon to have to do all GUI updates from the main thread. It is likely that SFML is not even thread-safe. You need to communicate from your other threads to the main thread and let them do things like window.close().
If I modify your example and simply return from the second thread instead of calling window.close(), it does not crash.

C++ std::thread makes segmentation fault error when it was used with SFML [duplicate]

im new to sfml and c++.and I have a project that uses the sfml library's to draw the graphics but when I add an additional thread to my program it fails to execute the code inside the thread. this is my code:(please help me!)
#include <SFML\Graphics.hpp>
#include <SFML\window.hpp>
#include <SFML\system.hpp>
#include <iostream>
#include <thread>
#include <chrono>
using namespace std;
int h(sf::RenderWindow* win){
//do something
win->close();
this_thread::sleep_for(chrono::milliseconds(10));
return 0;
}
int main(){
sf::RenderWindow window(sf::VideoMode(800,600),"My window");
thread t1(h,&window);
_sleep(10000000);
t1.join();
return 0;
}
http://www.sfml-dev.org/tutorials/2.0/graphics-draw.php#drawing-from-threads
SFML supports multi-threaded drawing, and you don't even have to do
anything to make it work. The only thing to remember is to deactivate
a window before using it in another thread; that's because a window
(more precisely its OpenGL context) cannot be active in multiple
threads at the same time.
call window.setActive(false); in your main(), before you pass it off to the thread.
And remember that you must handle events in the GUI thread (the main thread) for maximum portability.

std::thread crash in Debug mode (Work in run) with Netbeans/Cygwin

I'm trying to debug (GDB) my application developped with Cygwin under Windows.
When I debug this, I got "Signal received: ? (Unknown signal)" when the thread is created and the program stop.
#include <iostream>
#include <thread>
using namespace std;
void ConnectionTimer()
{
}
int main(int argc, char** argv) {
cout<<"Before thread creation"<<endl;
std::thread t( ConnectionTimer);
cout<<"After thread creation"<<endl;
t.join();
cout<<"After join"<<endl;
return 0;
}
The debugger stop at the line
status = NtCreateMutant (&mtx, MUTEX_ALL_ACCESS, &attr, bInitialOwner);in kernel32.cc.
It work as expected in run mode but crash in debug.
Result in run mode :
Before thread creation
After thread creation
After join
Result in debug mode (before crash):
Before thread creation
Any ideas what i'm missing ?
EDIT
If I comment thread related lines, it work properly.
Call Stack
Signal caught which cause crash
Discard
Configuration :
Cygwin 3.1.4-1 on W10 under GDB 8.2.1-1, compiled with g++ (GCC) 9.2.0-3
I found the reason of the crash.
My antivirus (Trend) was blocking the program, I had to create an exception for the exe and everything is now working fine.

Is there a simple way to play a sound in a background thread using SFML

I am trying to play a song in a background thread of my GUI application so that the song doesn't block the GUI thread. Is there a simple way to do this with either std::thread or SFML Threads?
I have tried using std::thread for this, but it still blocks the GUI thread when I call my_thread.join().
Here is an example of what I want to do:
#include <thread>
#include <SFML/Audio.hpp>
#include <unistd.h>
#include <iostream>
void func() {
sf::Music music;
music.openFromFile("mysong.wav");
music.play();
// if I don't have usleep here the function exits immediately
// why is that exactly???
usleep(100000000);
}
int main() {
std::thread my_thread(func);
my_thread.join();
// this is where I would process events/build windows in GUI
while(1)
std::cout << "here"; // <--- Want this to run while song plays
}
in SFML you need to have a valid sf::Sound or sf::Music for music to play, when that variable gets destroyed you will no longer have a valid reference to that object a possible solution for the code you posted would be something like this:
#include <SFML/Audio.hpp>
#include <unistd.h>
#include <iostream>
class CAudio
{
sf::Music music;
public:
void func()
{
music.openFromFile("mysong.wav");
music.play();
}
sf::Status getStatus()
{
return music.getStatus();
}
}
int main() {
CAudio my_music;
my_music.func();
// http://www.sfml-dev.org/documentation/2.0/SoundSource_8hpp_source.php
while(my_music.getStatus() == sf::Status::Playing)
{
std::cout << "here"; // <--- Want this to run while song plays
}
}
Also, always use brackets, regardless if its a 1 line statement always use brackets, I know its allowed but it will make your life easier when you troubleshoot later on.

SFML fails in multithreading

im new to sfml and c++.and I have a project that uses the sfml library's to draw the graphics but when I add an additional thread to my program it fails to execute the code inside the thread. this is my code:(please help me!)
#include <SFML\Graphics.hpp>
#include <SFML\window.hpp>
#include <SFML\system.hpp>
#include <iostream>
#include <thread>
#include <chrono>
using namespace std;
int h(sf::RenderWindow* win){
//do something
win->close();
this_thread::sleep_for(chrono::milliseconds(10));
return 0;
}
int main(){
sf::RenderWindow window(sf::VideoMode(800,600),"My window");
thread t1(h,&window);
_sleep(10000000);
t1.join();
return 0;
}
http://www.sfml-dev.org/tutorials/2.0/graphics-draw.php#drawing-from-threads
SFML supports multi-threaded drawing, and you don't even have to do
anything to make it work. The only thing to remember is to deactivate
a window before using it in another thread; that's because a window
(more precisely its OpenGL context) cannot be active in multiple
threads at the same time.
call window.setActive(false); in your main(), before you pass it off to the thread.
And remember that you must handle events in the GUI thread (the main thread) for maximum portability.