Exiting two concurrent queues with three threads in c++ - c++

I'm having problems with quitting my multithreaded, multi-queued c++ program. The diagram shows the queue and thread structure. The diagram is here: http://i.stack.imgur.com/JGhXs.png
In short, I have three threads, and two concurrent queues. The second_handler(second_thread) pops from the first queue and pushes to the second queue. All (seems to) works fine, until I want to quit the program by hitting a keyboard key. I get this error:
terminate called after throwing an instance of 'boost::exception_detail::clone_impl >'
what(): boost::lock_error
Aborted
Here is my code:
main
int main() {
startMultiThreading();
cout <<"I"<<endl;
}
startMultiThreading
void startMultiThreading() {
boost::thread_group someVar_workers;
boost::thread_group someOtherVar_workers;
concurrent_queue<someVar* > someVar_queue(&someVar_workers);
concurrent_queue<someOtherVar*> someOtherVar_queue(&someOtherVar_workers);
boost::thread *first_thread = new boost::thread(first_handler, &someVar_queue);
boost::thread *second_thread = new boost::thread(second_handler, &someVar_queue, &someOtherVar_queue);
boost::thread *third_thread = new boost::thread(third_handler, &someOtherVar_queue);
someVar_workers.add_thread(first_thread);
someVar_workers.add_thread(second_thread);
someOtherVar_workers.add_thread(second_thread);
someOtherVar_workers.add_thread(third_thread);
while (true) {
if (thread_should_exit) {
cout << "threads should be killed" << endl;
while (!someVar_queue.empty()) {
usleep(1000);
}
someVar_workers.remove_thread(second_thread);
while (!someOtherVar_queue.empty()) {
usleep(1000);
}
someOtherVar_queue.cancel();
someVar_workers.join_all();
someOtherVar_workers.remove_thread(second_thread);
someOtherVar_workers.join_all();
break;
}
usleep(10000);
}
cout << "H" << endl;
}
What I would like is the program to finish both queues and then terminates normally. What I would expect is to see "I" printed before the program to terminate. Here is the output:
End of first_handler
threads should be
second_handler is canceled
End of second_handler
H
terminate called after throwing an instance of 'concurrent_queue<someOtherVar*>::Canceled'
Aborted
Press [Enter] to close the terminal ...
What am I doing wrong when closing the threads and the queues?
Thank you

First, see comment from KillianDS - your example is too long.
The other thing is: Do never call a destructor directly!!
The destructor is something special and the language garantuees to call it at the end of scope of the variable. If you call it manually, it will get called a second time which most probably leeds to undefined behaviour.
Calling destructor manually

Related

C++ cancelling a pthread using a secondary thread stuck in function call

I'm having trouble instituting a timeout in one of my pthreads. I've simplified my code here and I've isolated the issue to be the CNF algorithm I'm running in the thread.
int main(){
pthread_t t1;
pthread_t t2;
pthread_t t3; //Running multiple threads, the others work fine and do not require a timeout.
pthread_create(&t1, nullptr, thread1, &args);
pthread_join(t1, nullptr);
std::cout << "Thread should exit and print this\n"; //This line never prints since from what I've figured to be a lack of cancellation points in the actual function running in the thread.
return 0;
}
void* to(void* args) {
int timeout{120};
int count{0};
while(count < timeout){
sleep(1);
count++;
}
std::cout << "Killing main thread" << std::endl;
pthread_cancel(*(pthread_t *)args);
}
void *thread1 (void *arguments){
//Create the timeout thread within the CNF thread to wait 2 minutes and then exit this whole thread
pthread_t time;
pthread_t cnf = pthread_self();
pthread_create(&time, nullptr, &timeout, &cnf);
//This part runs and prints that the thread has started
std::cout << "CNF running\n";
auto *args = (struct thread_args *) arguments;
int start = args->vertices;
int end = 1;
while (start >= end) {
//This is where the issue lies
cover = find_vertex_cover(args->vertices, start, args->edges_a, args->edges_b);
start--;
}
pthread_cancel(time); //If the algorithm executes in the required time then the timeout is not needed and that thread is cancelled.
std::cout << "CNF END\n";
return nullptr;
}
I tried commenting out the find_vertex_cover function and add an infinite loop and I was able to create a timeout and end the thread that way. The function is actually working the exact way it should. It should take forever to run under the conditions I'm running it at and therefore I need a timeout.
//This was a test thread function that I used to validate that implementing the timeout using `pthread_cancel()` this way works. The thread will exit once the timeout is reached.
void *thread1 (void *args) {
pthread_t x1;
pthread_t x2 = pthread_self();
pthread_create(&x1, nullptr, to, &x2);
/*
for (int i = 0;i<100; i++){
sleep(1);
std::cout << i << std::endl;
}
*/
}
Using this function I was able to validate that my timeout thread approach worked. The issue is when I actually run the CNF algorithm (using Minisat under the hood) once find_vertex_cover runs, there is no way to end the thread. The algorithm is expected to fail in the situation I'm implementing which is why a timeout is being implemented.
I've read up on using pthread_cancel() and while it isn't a great way it's the only way I could implement a timeout.
Any help on this issue would be appreciated.
I've read up on using pthread_cancel() and while it isn't a great way [..]
That's right. pthread_cancel should be avoided. It's especially bad for use in C++ as it's incompatible with exception handling. You should use std::thread and for thread termination, you can possibly use conditional variable or a atomic variable that terminates the "infinite loop" when set.
That aside, cancellation via pthread_cancel depends on two things: 1) cancellation state 2) cancellation type.
Default cancellation state is enabled. But the default cancellation type is deferred - meaning the cancellation request will be delivered only at the next cancellation point. I suspect there's any cancellation points in find_vertex_cover. So you could set the cancellation type to asynchronous via the call:
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
from the thread(s) you want to be able to cancel immediately.
But again, I suggest to not go for pthread_cancel approach at all and instead rewrite the "cancel" logic so that it doesn't involve pthread_cancel.

How can I create so many threads in c++ on beaglebone black

I want to create over 500 threads in c++ on beaglebone black
but the program has errors.
could you explain why the errors is occured and how I fix the errors
in thread func. : call_from_thread(int tid)
void call_from_thread(int tid)
{
cout << "thread running : " << tid << std::endl;
}
in main func.
int main() {
thread t[500];
for(int i=0; i<500; i++) {
t[i] = thread(call_from_thread, i);
usleep(100000);
}
std::cout << "main fun start" << endl;
return 0;
}
I expects
...
...
thread running : 495
thread running : 496
thread running : 497
thread running : 498
thread running : 499
main fun start
but
...
...
thread running : 374
thread running : 375
thread running : 376
thread running : 377
thread running : 378
terminate called after throwing an instance of 'std::system_error'
what(): Resource temporarily unavailable
Aborted
could you help me?
The beaglebone black appears to have a maximum of 512MB of DRAM.
The minimum stack size of a thread according to pthread_create() is 2MB.
i.e. 2^29 / 2^21 = 2^8 = 256. So what you're probably seeing around thread 374 is the allocator cannot free memory fast enough to meet the demand which
is handled by throwing an exception.
If you really want to see this explode, try moving that sleep call inside your thread function. :)
You could try preallocating the stack to 1MB or less (pthreads), but that has it's
own set of problems.
The questions to really ask yourself is:
Is my application io bound or compute bound?
What's my memory budget to run this application? If you spend your entire physical memory
on thread stacks, you'll have nothing left for the shared program heap.
Do I really need this much parallelism to do the job? The A8 is a single core machine BTW.
Could I solve the problem using a thread pool? Or not use threads at all?
Finally, you can't set the stack size in std::thread api, but you can in
boost::thread.
Or just write a thin wrapper around pthreads (assuming Linux).
Whenever you use threads, there are three parts.
Start the threads
Do the work
Release the thread
You're starting the threads and doing the work, but you're not releasing them.
Releasing threads. There are two options for releasing a thread.
You can join the thread (which basically waits for it to finish)
You can detach the thread, and let it execute independently.
In this particular case, you don't want the program to finish until all threads are done executing, so you should join them.
#include <iostream>
#include <thread>
#include <vector>
#include <string>
auto call_from_thread = [](int i) {
// I create the entire message before printing it, so that there's no interleaving of messages between threads
std::string message = "Calling from thread " + std::to_string(i) + '\n';
// Because I only call print once, everything gets printed together
std::cout << message;
};
using std::thread;
int main() {
thread t[500];
for(int i=0; i<500; i++) {
// Here, I don't have to start the thread with any delay
t[i] = thread(call_from_thread, i);
}
std::cout << "main fun start\n";
// I join each thread (which waits for them to finish before closing the program)
for(auto& item : t) {
item.join();
}
return 0;
}

is it possible to terminate a thread with another thread in c++?

I want to write a program in which many functions run simultaneously. I already figured out that in order to do that I need to use threads.
In my program a routine of heating and rotating an object with different temperatures and velocities has to run for a determined period of time in a loop. Once the time has passed I want the process to continue with my next heating/rotating (...). My idea was to write a "timer thread" that is able to end the current routine in some way, and skip to the next one. Is this possible?
I suppose most ways to do this are going to involve a shared flag between the working thread and the thread that signals it to stop working.
So you might have something along these lines:
// Use a std::atomic_bool to signal the thread safely
void process_stuff(std::atomic_bool& stop_processing)
{
while(!stop_processing) // do we keep going?
{
// do some measurements or action
std::this_thread::sleep_for(std::chrono::milliseconds(1)); // wait for next action
}
}
Elsewhere in another thread ...
std::atomic_bool stop_processing{false};
// start thread (use std::ref() to pass by reference)
std::thread proc_thread(process_stuff, std::ref(stop_processing));
// wait for some time...
std::this_thread::sleep_for(std::chrono::seconds(3));
stop_processing = true; // signal end
proc_thread.join(); // wait for end to happen
// now create a new thread...
In the initiating thread, by changing the value of the variable stop_processing you signal the running thread to stop looping, in which case it ends gracefully.
Check this:
int main() {
// first thread
auto thread1 = std::make_unique<std::thread>([]() {
std::this_thread::sleep_for(std::chrono::seconds(1));
std::cout << "over\n";
});
// disposing to second thread
std::thread([thread2 = std::move(thread1)](){
thread2->join();
}).detach();
//spinning a new thread
thread1.reset(new std::thread([]() {
std::this_thread::sleep_for(std::chrono::seconds(1));
std::cout << "next over\n";
}));
thread1->join();
return 0;
}

How can I Resume Thread once join() is called?

This is my sender thread once after it is called for first time its finish its execution. I Couldn't be able to resume this sender thread. Is There any mechanism in C++ to resume threads.
void ClientSocket::sender()
{
char buf[1024];
//readBuffer = m_ptrsendStream->Read_Adt(filePath);
//readStream();
//cout << readBuffer.str()<<endl;
cout << "write stream to send through socket\n" << endl;
cin >> buf;
if (isConnected == 0)
{
//send(clientSock, readBuffer.str().c_str(), strlen((char *)readBuffer.str().c_str()), 0);
send(clientSock, buf, strlen(buf), 0);
cout << "sending stream :\n"<<endl << buf << endl;
}
}
//this is where my thread creation happens and join() happens.
int main(int argc, char *argv[])
{
ClientSocket objSocket(argv[1]);
sender_thread = make_shared<thread>([&objSocket]() {
objSocket.sender();
});
try
{
if (sender_thread->joinable())
sender_thread->join();
}
No, once your thread has joined it's done and you need to create a new one.
If you have this pattern where you are constantly creating new threads it might be worthwhile to think about using a threadpool to avoid the overhead of constantly spawning new threads.
In addition, if this is related to networking it's probably best to avoid using threads and instead use something asynchronous like boost::asio.
Terminated threads cannot be resumed (this is not a C++ limitation, but a general limitation; when speaking about resuming thread, it is usually about resuming after previously suspending it).
After join() has returned, corresponding thread is already terminated; it has no state (except maybe for zobmie stuff and return code, but this is of no use for your purposes), and there is nothing to resume
However, it is possible to run your sender() function in another thread, just create another instance of your thread.
EDIT: I concur with #inf on using asio instead of threads whenever possible.
You want resume thread which is completed , normally thread resume used continue from suspended threads . Instead of resuming the thread ,stop come of thread un till it finish all actions , make use of while or wait in thread .

Thread is blocking whole program

I'm trying to make a multiclient server. I have this thread:
void client_thread(int new_socket)
{
int size;
char inbuffer[BUF];
do
{
cout << "Waiting for messages: " << endl;
size = recv(new_socket, inbuffer, BUF, 0);
} while (true);
}
and this main procedure:
int main()
{
while (true)
{
//waiting for clients
cout << "Waiting for connections..." << endl;
new_socket = accept ( create_socket, (struct sockaddr *) &cliaddress, &addrlen );
//new client connected
if (new_socket > 0)
{
//start thread
thread(client_thread, new_socket).join();
}
}
return 0;
}
When the first client connects, the thread starts and the server is waiting for messages from him. But the server doesn't wait for new clients anymore. I don't know why. Is it because of the infinite do-while loop inside the thread-function? What's the point of threads if they block your whole program if they contain infinite loops?
The main routine blocks, because it waits for the thread to finish: join().
If you don't want to block, then don't join() your client_thread.
This exception might come from the destruction of your anonymous thread object. When you leave the scope of if() all objects in this scope are destroyed. From http://en.cppreference.com/w/cpp/thread/thread/~thread you can see, the destructor calls terminate(). To avoid it, you can call detach(). So instead of thread(client_thread, new_socket).join();, you must say thread(client_thread, new_socket).detach();.
You are supposed to create a thread and keep a reference to it until you joined it. In your code, the thread object is deallocated right after being created, hence your error if don't call join immediately.
To achieve this properly, the best way is to allocate the object on the heap, using the operator new and store the pointer in a list somewhere. When the thread is done it may remove itself from the list (don't forget to "mutex" it), or you could have another dedicated thread do that: perhaps you could simply have your main thread join all the other threads before exiting.