I'm developing a fuse filesystem and before calling fuse_main_real() I'm starting a std::thread in a class instance to do some background work.
this->t_receive = new std::thread([this] { this->receive(); });
However, it seems like fuse_main_real() kills this thread when going into background.
If I start the program with the -f option, which tells fuse to stay in the foreground, the problem does not occur and the thread survives.
I'm not sure what fuse does to go into background.
How do I make my thread survive being backgrounded?
Edit: Here's a basic example that exposes the problem:
#define FUSE_USE_VERSION 30
#include <iostream>
#include <thread>
#include <fuse.h>
static void thread_method()
{
while (true)
{
std::cout << "test" << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
struct testop : fuse_operations
{ };
static struct testop ops;
int main(int argc, char** argv)
{
std::thread(thread_method).detach();
fuse_main_real(argc, argv, &ops, sizeof(fuse_operations), NULL);
}
Compile with
g++ -D_FILE_OFFSET_BITS=64 `pkg-config --cflags fuse` -lfuse -lpthread -std=c++14 -o test.o test.cpp
Command that works (repeatedly says "test"):
./test.o -f /home/test/testmountpoint
Command that doesn't work and shows the problem (says "test" once):
./test.o /home/test/testmountpoint
The libfuse wiki says that
Miscellaneous threads should be started from the init() method. Threads started before fuse_main() will exit when the process goes into the background.
Related
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.
I have a problem with using Threads in C++. I read this topic:
How to make CDT/Eclipse work with C++11 threads?
But it didn't help at all :(
So, from the beginning. I'm trying to 'convert' big project from Visual Studio into Eclipse and I'm forcing with a problem with threads. So I created another Eclipse project in order to test that.
#include <iostream>
#include <thread>
void worker()
{
std::cout << "hello from worker" << std::endl;
}
int main(int argc, char **argv)
{
std::thread t(worker);
t.join();
}
But, I get:
error: 'thread' is not a member of 'std'
In GCC C++ Compiler->Miscellaneous I have
-c -fmessage-length=0 -std=c++11 -pthread
In MinGW C++ Linker->Libraries I have
pthread
Even in MinGW C++ Linker->Miscellaneous I have
-std=c++11
I'm a fresh user of Eclipse and I have no idea what I'm doing wrong.
I would be very grateful for any tips :)
I'm creating my first GUI application with C++ using gtkmm and Glade.
I had to merge various tutorials, because none I found is supporting Glade in combination with Gtk::Application and various classes.
See the code below:
main.cpp
int main(int argc, char **argv)
{
std::cout << "Start" << std::endl;
auto app = Gtk::Application::create(argc,argv,"org.gtkmm.ex");
auto builder = Gtk::Builder::create();
builder->add_from_file("gui02.glade");
HelloWorld* helloworld;
std::cout << "helloworld compl." << std::endl;
app->run(*helloworld);
return 0;
}
helloworld.hpp
#include <gtkmm.h>
class HelloWorld : public Gtk::Window
{
protected:
Glib::RefPtr<Gtk::Builder> builder;
Gtk::Button *btn1;
Gtk::Label *lb1;
public:
HelloWorld(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& refGlade);
protected:
void on_button1_clicked();
};
helloworld.cpp
#include "helloworld.hpp"
using namespace std;
using namespace Gtk;
HelloWorld::HelloWorld(BaseObjectType* cobject, const Glib::RefPtr<Gtk::Builder>& refGlade) :
Gtk::Window(cobject), builder(refGlade)
{
builder->get_widget("label1", lb1);
builder->get_widget("button1", btn1);
btn1->signal_clicked().connect(sigc::mem_fun(*this, &HelloWorld::on_button1_clicked));
}
void HelloWorld::on_button1_clicked()
{
lb1->set_text("HW!");
}
Compiling using:
g++ main.cpp helloworld.cpp -o main `pkg-config gtkmm-3.0 --cflags --libs`
Result in the command line:
Start
helloworld compl.
Segmentation fault (core dumped)
Debugging with gdb (relevant extract, you get the full output if neccessary)
Glib::RefPtr::operator-> (this=0x7fffffffdd10) at /usr/include/glibmm-2.4/glibmm/refptr.h:260
260 return pCppObject_;
Thread 1 "main" received signal SIGSEGV, Segmentation fault.
0x00007ffff7a4799e in Gtk::Widget::signal_hide() () from /usr/lib/x86_64-linux-gnu/libgtkmm-3.0.so.1
Because I'm quite new to C++ (having some experience with C#), I'm not so used to pointers. Where is the error in this case?
Using a different code, where I create a Window* and use "app->run(*window)" works pretty fine, so the error occurs somewhere in the new app->run() and the outsourcing in class "HelloWorld".
Your code crashes here app->run(*helloworld);
You try to dereference an empty pointer. That pointer does not point to an object in memory.
Do it like this:
HelloWorld* helloworld = new HelloWorld();
std::cout << "helloworld compl." << std::endl;
app->run(*helloworld);
I am new to C++ and to gtkmm. I am currently trying to compile a tutorial I found online using a window and a button. I am compiling in Ubuntu 12.04. I can compile a single file fine but when I try to compile several files using a Makefile I get an error that I don't understand:
sarah#superawesome:~/gtkexample$ make
g++ -c main.cc
In file included from HelloSarah.h:4:0,
from main.cc:1:
/usr/include/gtkmm-3.0/gtkmm/button.h:7:28: fatal error: glibmm/ustring.h: No such file or directory
compilation terminated.
make: *** [main.o] Error 1
I really don't understand the error, I've been searching for hours. I would really appreciate any help or insight into my problem.
These are my 3 files and Makefile:
#ifndef GTKMM_HELLOSARAH_H
#define GTKMM_HELLOSARAH_H
#include <gtkmm-3.0/gtkmm/button.h>
#include <gtkmm/window.h>
class HelloSarah : public Gtk::Window
{
public:
HelloSarah();
virtual ~HelloSarah();
protected:
//Signal handlers:
void on_button_clicked();
//Member widgets:
Gtk::Button m_button;
};
#endif
and
main.cc
#include "HelloSarah.h"
#include <gtkmm/application.h>
int main (int argc, char *argv[])
{
Glib::RefPtr<Gtk::Application> app = Gtk::Application::create(argc, argv, "org.gtkmm.example");
HelloSarah hellosarah;
//Shows the window and returns when it is closed.
return app->run(hellosarah);
}
and HelloSarah.cc
#include "helloSarah.h"
#include <iostream>
HelloSarah::HelloSarah()
: m_button("Hello Sarah") // creates a new button with label "HelloSarah".
{
// Sets the border width of the window.
set_border_width(10);
// When the button receives the "clicked" signal, it will call the
// on_button_clicked() method defined below.
m_button.signal_clicked().connect(sigc::mem_fun(*this,
&HelloSarah::on_button_clicked));
// This packs the button into the Window (a container).
add(m_button);
// The final step is to display this newly created widget...
m_button.show();
}
HelloSarah::~HelloSarah()
{
}
void HelloSarah::on_button_clicked()
{
std::cout << "Hello Sarah" << std::endl;
}
and finally my Makefile:
app: main.o HelloSarah.o
g++ -o app main.o HelloSarah.o
main.o: main.cc HelloSarah.h
g++ -c main.cc
HelloSarah.o: HelloSarah.cc HelloSarah.h
g++ -c HelloSarah.cc
clean:
rm -f *.o app
The following include statement in your example is not correct. It works only because the file path is relative to the standard /usr/include/ directory, but the include statement in button.h does not, so you get an error message.
#include <gtkmm-3.0/gtkmm/button.h>
You have to tell g++ where the necessary include files and shared objects can be found. You can use the output of pkg-config to do that job.
pkg-config --cflags --libs gtkmm-3.0
The whole g++ command should be something like that.
g++ `pkg-config --cflags --libs gtkmm-3.0` -c HelloSarah.cc
After that you can simply use the include line in gtkmm Hello World.
#include <gtkmm/button.h>
I had this problem too on Ubuntu.
The solution:
sudo apt-get install libgtkmm-3.0-dev
You can use any version as you need.
Tried the following example compiled with g++ -std=gnu++0x t1.cpp and g++ -std=c++0x t1.cpp but both of these result in the example aborting.
$ ./a.out
terminate called after throwing an instance of 'std::system_error'
what():
Aborted
Here is the sample:
#include <thread>
#include <iostream>
void doSomeWork( void )
{
std::cout << "hello from thread..." << std::endl;
return;
}
int main( int argc, char *argv[] )
{
std::thread t( doSomeWork );
t.join();
return 0;
}
I'm trying this on Ubuntu 11.04:
$ g++ --version
g++ (Ubuntu/Linaro 4.5.2-8ubuntu4) 4.5.2
Anyone knows what I've missed?
You have to join std::threads, just like you have to join pthreads.
int main( int argc, char *argv[] )
{
std::thread t( doSomeWork );
t.join();
return 0;
}
UPDATE: This Debian bug report pointed me to the solution: add -pthread to your commandline. This is most probably a workaround until the std::thread code stabilizes and g++ pulls that library in when it should (or always, for C++).
Please use the pthread library during the compilation: g++ -lpthread.
Simplest code to reproduce that error and how to fix:
Put this in a file called s.cpp:
#include <iostream>
#include <stdlib.h>
#include <string>
#include <unistd.h>
#include <thread>
using namespace std;
void task1(std::string msg){
cout << "task1 says: " << msg;
}
int main(){
std::thread t1(task1, "hello");
usleep(1000000);
t1.detach();
}
Compile like this:
el#apollo:~/foo7$ g++ -o s s.cpp -std=c++0x
Run it like this, the error happens:
el#apollo:~/foo7$ ./s
terminate called after throwing an instance of 'std::system_error'
what(): Operation not permitted
Aborted (core dumped)
To fix it, compile it like this with the -pthread flag:
g++ -o s s.cpp -std=c++0x -pthread
./s
Then it works correctly:
task1 says: hello
For what it's worth, I had different issue with similar code using threads in g++ (MinGW). Work-around was to put some "delay" between creating a thread and joining it.
Code with infrequently failing assertion:
std::atomic_bool flag{false};
std::thread worker( [&] () { flag.store(true); } );
worker.join();
assert(flag.load()); // Sometimes fails
Work-around:
std::atomic_bool flag{false};
std::thread worker( [&] () { flag.store(true); } );
while (not flag.load()) { std::this_thread::yield(); }
worker.join();
assert(flag.load()); // Works fine
Note that yield() alone did not help, hence the while loop. Using sleep_for(...) also works.
You need to link to run time library