I am trying to use multithread for connecting for more then one peer simultinaly.
While I am running my code and run more then a one thread the program crashes in the "connect" function and it writes: "Abort() has been called".
This is How I call to the threads:
TcpPeers(OrderedMap<std::string, unsigned short> peers, std::string infoHash)
{
this->peers = peers;
peersArr = new Peer[peers.GetSize()];
for (int i = 0; i < peers.GetSize(); i++)
{
Peer * pp = new Peer(peers.GetKeyByIndex(i), peers.GetValueByIndex(i), infoHash);
*(peersArr + i) = *pp;
}
for (int i = 0; i < peers.GetSize(); i++)
{
std::thread t1(&Peer::CreateConnection, *(peersArr + i));
}
}
A peer is another client that I need to connect with while I am trying to implement the bittorent protocol.
Again, when there is one thread all goes right, when I have more then two peers all crashes.
When a std::thread object gets destroyed it is not allowed to be joinable(), i.e., one of two things have to happen before it is destroyed:
It was detached and the thread has gone into the wild and there is pretty much no control over whether it has finished or not.
The thread has been join()ed.
If a std::thread object is destroyed without either of these states, std::terminate() is called which is probably the cause for the call to abort() you observe. In your loop you keep destroying threads without having called either detach() or join() on them. The system sees that as a request to terminate your program.
In case you need a reference for this behavior: see 30.3.1.3 [thread.thread.destr] paragraph 1:
~thread();
If joinable(), calls std::terminate(). Otherwise, has no effects. [ Note: Either implicitly detaching or joining a joinable() thread in its destructor could result in difficult to debug correctness (for detach) or performance (for join) bugs encountered only when an exception is raised. Thus the programmer must ensure that the destructor is never executed while the thread is still joinable. —end note ]
Related
This question already has answers here:
Starting thread causing abort()
(2 answers)
std::thread causes program to abort
(1 answer)
Closed 1 year ago.
Why using delete in a thread fails, but not if called synchronously ?
class dummyclass{};
main()
{
vector<dummyclass*> testlist{};
for(int i=0; i<5; i++)
{
auto value = new dummyclass();
testlist.push_back(value);
}
thread cleanuptest([&]() {for (auto x : testlist) delete x;}); // fails (abort())
}
EDIT/COMMENT
detach and join are the right solutions.
In the case main() is actually a method in a bigger program, which continues to live, detach() is interesting.
In the case of unit tests, then calling join() in the destructor of the class to test is cleaner.
The problem with your program is that your main() function exits before the cleanuptest() thread has a chance to run to completion, taking the testlist object with it. So when cleanuptest() runs, it will likely be trying to access a vector that has already been destroyed (or is in the process of being destroyed, depending on the timing of when the threads execute; they are running asynchronously with respect to each other so their relative timing is indeterminate).
The other problem (which is likely the source of the abort() call) is that the std::thread destructor is detecting that you are destroying the thread object without having called either join() or detach() on it first, which is considered a programming error.
The fix is easy, just add this line to the bottom of main():
cleanuptest.join();
The join() method won't return until the child thread has exited, so it will guarantee that testlist remains valid until the child thread is done using it.
Your main is finishing before the thread has a chance to finish which is causing the abort. You should cleanuptest.join() the thread to let it finish before main exits.
Is there a way to cancel a boost::thread from another as in the following?:
boost::thread* thread1(0);
boost::thread* thread2(0);
thread2 = new boost::thread([&](){
//some expensive computation that can't be modified
if(thread1)
thread1->interrupt();
});
thread1 = new boost::thread([&]() {
//some other expensive computation that can't be modified
if(thread2)
thread2->interrupt();
});
thread1->join();
thread2->join();
delete thread1;
delete thread2;
Right now both expensive computations finish without being interrupted. I had figured the joins would be treated as an interruption point, and the main thread would continue after one of the two expensive computations completed.
In general, there is no portable way for one thread to terminate another, without cooperation from the thread being terminated. This question comes up once in a while, it seems (see here and here - although your question is not an exact duplicate).
Barring cooperation from the thread being interrupted (which would have to perform seppuku on notification), if you would like the main thread to continue after the first of the threads has terminated, you could make a condition that each of the child threads fires when it ends.
At this point, you could either let the other thread continue running (possibly detaching it), or just terminate everything.
A non-portable solution for POSIX-compliant systems (e.g. Linux) would be to use pthread_cancel() and then pthread_join() on the Boost thread's native_handle() member, which is of type pthread_t (again, only on POSIX-compliant systems. I can't speak for other systems, like Windows).
Also, you must use a boost::scoped_thread instead of just a boost::thread so that you can "override" (not in the OO-sense) the join/detach behavior that Boost will do when the thread is destroyed. This is necessary because when you call pthread_cancel then pthread_join on a boost::thread, the boost::thread object is still 'joinable' (i.e. boost::thread::joinable() returns true), and so the destructor will exhibit undefined behavior, per the documentation.
With all that being said, if a platform-dependent solution for cancelling threads like this is necessary in your application, I'm not sure there's much to be gained from using boost::threads over plain-old pthreads; still, I suppose there may be a use case for this.
Here's a code sample:
// compilation: g++ -pthread -I/path/to/boost/include -L/path/to/boost/libs -lboost_thread main.cpp
#include <cstdio>
#include <pthread.h>
#include <boost/thread/scoped_thread.hpp>
typedef struct pthreadCancelAndJoin
{
void operator()(boost::thread& t)
{
pthread_t pthreadId = t.native_handle();
int status = pthread_cancel(pthreadId);
printf("Cancelled thread %lu: got return value %d\n", pthreadId, status);
void* threadExitStatus;
status = pthread_join(pthreadId, &threadExitStatus);
printf("Joined thread %lu: got return value %d, thread exit status %ld\n",
pthreadId, status, (long)threadExitStatus);
}
} pthreadCancelAndJoin;
void foo()
{
printf("entering foo\n");
for(int i = 0; i < 2147483647; i++) printf("f"); // here's your 'expensive computation'
for(int i = 0; i < 2147483647; i++) printf("a");
printf("foo: done working\n"); // this won't execute
}
int main(int argc, char **argv)
{
boost::scoped_thread<pthreadCancelAndJoin> t1(foo);
pthread_t t1_pthread = t1.native_handle();
sleep(1); // give the thread time to get into its 'expensive computation';
// otherwise it'll likely be cancelled right away
// now, once main returns and t1's destructor is called, the pthreadCancelAndJoin
// functor object will be called, and so the underlying p_thread will be cancelled
// and joined
return 0;
}
pthread_cancel() will cancel your thread when it reaches a "cancellation point" (assuming the cancel type and cancel state are at their default values, which is the case for boost::thread objects); see the pthreads man page for a list of all cancellation points. You'll notice that those cancellation points include many of the more common system calls, like write, read, sleep, send, recv, wait, etc.
If your 'expensive computation' includes any of those calls down at its lowest level (e.g. in the code sample, printf eventually calls write), it will be cancelled.
Best of all, Valgrind reports no memory leaks or memory errors with this solution.
Finally, a note about your misconception in your question:
I had figured the joins would be treated as an interruption point...
join, or any of the boost::thread interruption functions, for that matter, is only treated as an interruption point for the thread that calls it. Since your main thread is calling join(), the main thread is the thread that experiences the interruption point, not the thread that it is trying to join. E.g. if you call thread1.interrupt() in some thread and then thread1 calls thread2.join(), then thread1 is the one that gets interrupted.
Learning C++ multi-threading.
In my example, thread helper1 and helper2 have finished executing before the main thread finished. However, program crashes. I specifically, took out .join() statements, to see how program would behave, expecting no errors, since main() calls std::terminate after two other threads have finished.
void foo()
{
// simulate expensive operation
std::this_thread::sleep_for(std::chrono::seconds(5));
std::cout << "t1\n";
}
void bar()
{
// simulate expensive operation
std::this_thread::sleep_for(std::chrono::seconds(1));
std::cout << "t2\n";
}
int main()
{
std::cout << "starting first helper...\n";
std::thread helper1(foo);
std::cout << "starting second helper...\n";
std::thread helper2(bar);
std::this_thread::sleep_for(std::chrono::seconds(10));
std::cout << "waiting for helpers to finish..." << std::endl;
//helper1.join();
//helper2.join();
std::cout << "done!\n";
}
I'd say that your question doesn't make sense, because it's based on a false assumption. The only way to know that a thread has finished is when the thread's join() returns. Before join() returns, it is not the case that "the thread has finished". It may be true that some statement within the thread's execution has completed (e.g. the printing of a message, or better, the writing of an atomic variable), but the completion of the thread function itself is not measurable in any way other than by joining.
So none of the threads "have finished" until you join them.
Because std::~thread calls terminate if the associated thread is still joinable:
30.3.1.3 thread destructor [thread.thread.destr]
~thread();
If joinable(), calls std::terminate(). Otherwise, has no effects. [
Note: Either implicitly detaching or joining a joinable() thread in its destructor could result in difficult to debug correctness (for detach) or performance (for join) bugs encountered only when an exception is raised. Thus the programmer must ensure that the destructor is never executed while the thread is still joinable. —end note]
You need to call either .detach() or .join(). Other than that, since you cannot be sure how the operating system schedules your threads, you could end up interrupting your threads any way, so better use .join() from the beginning.
Based on the reference, underlying thread must be joined or detached at the time the destructor is called. The destructor is invoked when main exits, and probably assumes that join or detach has been called.
The code should also not crash, as long as the following two lines are somewhere after helper1 and helper2 are constructed.
helper1.detach()
helper2.detach()
The CPU can schedule the three threads ( main / thread1 / thread2 ) in any order. It might happen that your main doesn't get a time to run and your threads exit. So, you need to keep keep join in main to take care of this case. Scheduling of threads is unpredictable, unless you are using an RTOS.
The program below will end up failing with a message regarding abort() being called.
I'm starting a thread that simple prints to cout. If I use std::this_thread::sleep_for(), I get the error. If I remove this, I get the error. If I call join() on the thread, everything works fine.
Shouldn't the thread have terminated long before the 1000 ms delay was up? Why is this causing an error? I can't believe calling join() is a requirement for a thread.
#include <thread>
#include <iostream>
class ThreadTest
{
public:
ThreadTest() : _t{ &ThreadTest::Run, this } {}
void Wait() { _t.join(); }
private:
void Run(){
std::cout << "In thread" << std::endl;
}
std::thread _t;
};
int main(int argc, char *argv[])
{
ThreadTest tt;
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
// tt.Wait();
return 0;
}
According to cppreference on thread class destructor :
~thread(): Destroys the thread object. If *this still has an associated running thread (i.e. joinable() == true), std::terminate() is called.
And joinable() :
[...] A thread that has finished executing code, but has not yet been joined is still considered an active thread of execution and is therefore joinable.
So you have to call join() explicitely before your thread variable is automatically destroyed or use the detach() member function.
Check cppreference's std::thread page.
A thread that has finished executing code, but has not yet been joined is still considered an active thread of execution and is therefore joinable.
[the destructor] Destroys the thread object. If *this still has an associated running thread (i.e. joinable() == true), std::terminate() is called.
To get the behavior you want, you'd need to call _t.detach() before exiting from main:
[detach()] Separates the thread of execution from the thread object, allowing execution to continue independently. Any allocated resources will be freed once the thread exits.
After calling detach *this no longer owns any thread.
struct Test {
bool active{true};
void threadedUpdate() {
std::this_thread::sleep_for(std::chrono::milliseconds(1));
if(!active) // crashes here after Test instance is destroyed
return;
}
Test() {
std::thread([this]{ while(true) threadedUpdate(); }).detach();
}
~Test() {
// somehow stop the detached thread?
}
};
When an instance of Test is initialized, it spawns and detaches an std::thread which runs in background. When the same instance is destroyed, the previously mentioned thread tries to access the active member, which was destroyed along with the instance, causing a crash (and an AddressSanitizer backtrace).
Is there a way to stop the detached thread on ~Test()?
The design is bad. How should a thread running in background until the caller is destroyed be spawned/handled correctly?
Make the thread a member of the class, and instead of detaching it in the constructor, join it in the destructor. To stop the thread from looping, you can have a boolean inside the class that signals whether the thread should continue running or not (std::atomic<bool> update).
The thread could be executing this: [this] { while (update) threadUpdate(); }.
In the destructor of your class, do update = false, and call thread.join()
You can't stop detached threads. That's the point of .detach() - you don't have any way to refer to the detached thread anymore, at least as far as the C++ standard specifies. If you want to keep a handle to the thread, store the std::thread and call .join() in the destructor.