How can I start a thread executing code from another object/class?
This is what I tried, but didn't work
#import <thread>
#import "Foo.h"
int main() {
Foo bar;
std::thread asyncStuff(bar.someMethod);
}
So why doesn't this work, and how can I solve it?
Solution:
Call std::thread asyncStuff(&Foo.someMethod, &bar); instead.
You want:
std::thread asyncStuff(&Foo::someMethod, &bar);
(Don't forget to join or detach the thread before destroying the std::thread object.)
Related
I was told if one thread got some error, the whole process would be stopped. I used the c++11 code as below to do a simple test:
#include <iostream>
#include <thread>
#include <chrono>
void func1()
{
std::this_thread::sleep_for(std::chrono::seconds(5));
std::cout<<"exception!!!"<<std::endl;
throw(std::string("exception"));
}
void func2()
{
while (true)
{
std::cout<<"hello world"<<std::endl;
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
int main()
{
std::thread t1(func1);
std::thread t2(func2);
t1.join();
t2.join();
return 0;
}
I compiled (g++ -std=c++11 -lpthread test.cpp) and executed it.
5 seconds later, I did get an error: Aborted (core dumped)
In my opinion, each thread has it own stack. In this example, if the stack of t1 dies, why can't the t2 continue?
As a thread only has its stack as private, all other things (heap, bss, data, text, env) are shared between threads. One thread crash will lead to the whole process crash, so t1 affected t2 in your program.
I code snipped below:
#include <iostream>
#include <thread>
class Me{
public:
bool isLearning;
void operator()(bool startLearning){
isLearning = startLearning;
}
};
int main(){
Me m;
std::thread t1(m(true));
t1.join();
std::cout << m.isLearning << std::endl;
}
I can't start thread with callable object when argument is passed, is there any way to start thread and pass callable object with argument in thread constructor?
Problem #1
std::thread t1(m(true)); does not do what you think it does.
In this case you are invoking your function object and passing it's result (which is void) to the constructor of std::thread.
Solution
Try passing your function object and arguments like this:
std::thread(m, true);
Problem #2
std::thread will take a copy of your function object so the one it uses and modifies will not be the same one declared in main.
Solution
Try passing a reference to m instead by using std::ref.
std::thread(std::ref(m), true);
std::thread t1(m, true);
Bear in mind that, absent proper synchronisation,
isLearning = startLearning;
and
std::cout << m.isLearning << std::endl;
executing simultaneously constitute a data race and undefined behaviour.
Don't forget to t1.join() in the end.
I am running this very simple program, on Ubuntu 13.04 Desktop, however if I comment out the line sleep_for, it hangs after printing cout from main. Can anyone explain why ? As far as I understand, main is a thread and t is another thread and in this case the mutex manages synchronization for shared cout object.
#include <thread>
#include <iostream>
#include <mutex>
using namespace std;
std::mutex mu;
void show()
{
std::lock_guard<mutex> locker(mu);
cout<<"this is from inside the thread"<<endl;
}
int main()
{
std::thread t(show);
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
std::lock_guard<mutex> locker(mu);
cout<<"This is from inside the main"<<endl;
t.join();
return 0;
}
If you change to main function as follows, the code will work as expected:
int main()
{
std::thread t(show);
{
std::lock_guard<mutex> locker(mu);
cout << "This is from inside the main" << endl;
} // automatically release lock
t.join();
}
In your code, there is a unfortunate race condition. If the thread t gets the lock first, everything works fine. But if the main threads gets the lock first, it holds the lock until the end of the main function. That means, the thread t has no chance to get the lock, can't finish and the main thread will block on t.join().
That's just a classic deadlock: The main thread obtains the lock and then blocks on joining the other thread, but the other thread can only join if it manages to obtain the lock.
I found that accessing tcp::socket from a std::thread will cause program terminated.
Here's the sample program from boost.
http://www.boost.org/doc/libs/1_53_0/doc/html/boost_asio/example/echo/blocking_tcp_echo_server.cpp
Compile it: g++ blocking_tcp_echo_server.cpp -std=c++11 -lboost_system -lboost_thread -pthread
So far, everthing works fine.
But if you replace the boost::thread with std::thread (and #include ), the program will crash(terminated) when it access sock member ( socket::read_some() ).
Error message: terminate called without an active exception.
Any idea?
That's the difference between boost::thread and std::thread. I have seen the code, and you can fix it to work with std::thread, just like this:
void server(boost::asio::io_service& io_service, short port) {
// ...
std::thread t(boost::bind(session, sock));
t.detach();
}
It seems you must detach or join the thread when you use std::thread.
Code:
#include <iostream>
#include <thread>
int main(void) {
std::thread t([](){std::cout << "will throw exception" << std::endl;});
// t.detach();
return 0;
}
It will throw exception if not detach or not join or not link pthread
I am working in the Linux environment, and I have a C++ program, what I want is when I cancel the program with ctrl+c I would like that the program executes a function, to close some files and print some sutff, is there any way to do this?. Thank you.
signal() can be dangerous on some OSes and is deprecated on Linux in favor of sigaction(). "signal versus sigaction"
Here's an example that I ran across recently ("Tap the interrupt signal") and modified as I was playing around with it.
#include<stdio.h>
#include<unistd.h>
#include<signal.h>
#include<string.h>
struct sigaction old_action;
void sigint_handler(int sig_no)
{
printf("CTRL-C pressed\n");
sigaction(SIGINT, &old_action, NULL);
kill(0, SIGINT);
}
int main()
{
struct sigaction action;
memset(&action, 0, sizeof(action));
action.sa_handler = &sigint_handler;
sigaction(SIGINT, &action, &old_action);
pause();
return 0;
}
For a full working example you can try the following code:
#include <signal.h>
#include <stdio.h>
#include <stdbool.h>
volatile bool STOP = false;
void sigint_handler(int sig);
int main() {
signal(SIGINT, sigint_handler);
while(true) {
if (STOP) {
break;
}
}
return 0;
}
void sigint_handler(int sig) {
printf("\nCTRL-C detected\n");
STOP = true;
}
Example run:
[user#host]$ ./a.out
^C
CTRL-C detected
You have to catch the SIGINT. Something like this:
void sigint_handler(int sig)
{
[do some cleanup]
signal(SIGINT, SIG_DFL);
kill(getpid(), SIGINT);
}
loads more detail here
Short answer: look into the signal function, specifically catching SIGINT. You write a callback function and pass it to the system via the signal function, then when that particular signal happens, the system calls your callback function. You can close files and do whatever other cleanup stuff you want in there.
Note to people who might stumble upon this question, looking for the answer in Windows instead:
Use the SetConsoleCtrlHandler API call to set a custom handler and watch for CTRL_C_EVENT, CTRL_BREAK_EVENT or CTRL_CLOSE_EVENT.