How to terminate a specific thread among other threads

Hello all . i have been trying to selectively dispose a thread among some other threads , but so far i wasnt successful in finding a way to do it . suppose i have a simple function which identifies any threads which gets into it and if a specific one is located ,it is disposed . simply sth like this : #include <boost/signal.hpp> #include <iostream> #include <boost/thread.hpp> using namespace std; boost::thread threadarray[3]; int t(int x) { boost::id id(); switch(boost::this_thread::get_id()) { case threadarray[0].get_id(): cout<<"thread 1"; break; case threadarray[1].get_id(): * DISPOSE THIS THREAD or CHANGE OWNERSHITP, OR GET ANOTHER JOB TO IT , OR CHECK IF IT WAS SUCCESSFUL OR NOT* break; case threadarray[3].get_id(): cout<<"thread 3"; break; default: cout<<"default"; } return 0; } int main() { boost::thread t1(t,5), t2(t,6),t3(t,7); threadarray[0] = t1.move(); threadarray[1] = t2.move(); threadarray[2] = t3.move(); for(int i = 0; i <3;i++) { threadarray[i].join(); } system("pause"); } i cant either use a switch statement to identify which thread im dealing with at the moment , nor can i find any means to keep track of my threads , and manage them in situations like this ( i already tried vector(boost::thread> my vect; and tries to use std::for_each(vect.begin(),vect.end(),somefunction_accepting boost::thread) , this doesnt work !! ) any idea how i can achieve sth similar? Thanks in advance

i have been trying to selectively dispose a thread among some other threads , but so far i wasnt successful in finding a way to do it . suppose i have a simple function which identifies any threads which gets into it and if a specific one is located ,it is disposed . simply sth like this :
#include <boost/signal.hpp> #include <iostream> #include <boost/thread.hpp> using namespace std; boost::thread threadarray[3];
int t(int x) { boost::id id(); switch(boost::this_thread::get_id()) { case threadarray[0].get_id(): cout<<"thread 1"; break; case threadarray[1].get_id(): DISPOSE THIS THREAD or CHANGE OWNERSHITP, OR GET ANOTHER JOB TO IT , OR CHECK IF IT WAS SUCCESSFUL OR NOT
To end the thread, just return from the thread function.

To end the thread, just return from the thread function.
Ok , how do i know which thread is the one im looking for ? i cant use switch statements .! and please note that i want to really get rid of the thread, i dont want to return each time it is spawned ! ( actaully returning means , get in the function , but dont do anything ! right? )

To end the thread, just return from the thread function.
Ok , how do i know which thread is the one im looking for ? i cant use switch statements .!
thread::id class has comparison operators, use "if": http://www.boost.org/doc/libs/1_49_0/doc/html/thread/thread_management.html#...
and please note that i want to really get rid of the thread, i dont want to return each time it is spawned ! ( actaully returning means , get in the function , but dont do anything ! right? )
Why is it spawned each time? Thread is a "thread of execution". When you launch it in c/c++, it starts in the beginning of some function and ends when the function ends. So if you return from the thread function, this particular thread exits.

Why is it spawned each time? Thread is a "thread of execution". When you launch it in c/c++, it starts in the beginning of some function and ends when the function ends. So if you return from the thread function, this particular thread exits.
thanks , thats great .:) i though the only way to terminate a thread is to use interrupts and an un-handled exception generated by sleep() :) by the way it is the source code whith my latest knowledge . it now compiles fine thanks to you guys , kills a thread , and then specifically i can manage each thread i want . but there is a problem , the first thread doesnt print anything on the cosole ! while the others do! i even used mutex , but seems its not the case . any idea? //in the name of GOD
//Seyyed Hossein Hasan Pour //Learning Boost Threading //How to selectively specify a thread and terminate it
#include <boost/signal.hpp> #include <iostream> #include <boost/thread.hpp> using namespace std;
boost::thread threadarray[3]; boost::mutex mutex; int t(int x) { if(threadarray[0].get_id() == boost::this_thread::get_id()) { boost::lock_guard<boost::mutex> locker(mutex); std::cout<<"thread 1"; } else if(threadarray[1].get_id() == boost::this_thread::get_id()) { return 0; } else if(threadarray[2].get_id() == boost::this_thread::get_id()) { boost::lock_guard<boost::mutex> locker(mutex); std::cout<<"thread 3"; } return 0; }
int main() { boost::thread t1(t,5), t2(t,6),t3(t,7);
threadarray[0] = t1.move(); threadarray[1] = t2.move(); threadarray[2] = t3.move();
for(int i = 0; i <3;i++) { threadarray[i].join(); } system("pause"); return 0; }

but there is a problem , the first thread doesnt print anything on the cosole ! while the others do! i even used mutex , but seems its not the case . any idea?
Your code is not thread-safe. See my comments below.
int t(int x) { if(threadarray[0].get_id() == boost::this_thread::get_id())
Here and below in this thread function you access "threadarray" without protecting it with mutex. <...>
int main() { boost::thread t1(t,5), t2(t,6),t3(t,7);
threadarray[0] = t1.move(); threadarray[1] = t2.move(); threadarray[2] = t3.move();
Here you write to "threadarray" without protecting it with a mutex. Besides, some (or all) the threads that you launched above might have been already executed their thread functions and exited - before you have a chance to store their objects in "threadarray".

Thanks for your meticulous observation :) so instead of just retyping lockguard inside all of if statements , one at the very beginning of the function in question would suffice right ? :) did your suggestions and the code is compiled just fine , and i get the expected behaviors :) this is the code i came up with so far : //in the name of GOD
//Seyyed Hossein Hasan Pour //Learning Boost Threading- How to end/terminate a thread //How to selectively specify a thread and terminate it
#include <boost/signal.hpp> #include <iostream> #include <boost/thread.hpp> using namespace std;
boost::thread threadarray[3]; boost::mutex mutex; int t(int someArg) { boost::lock_guard<boost::mutex> locker(mutex); if(threadarray[0].get_id() == boost::this_thread::get_id()) { std::cout<<boost::this_thread::get_id()<<"\t is thread 1 with arg "<<someArg<<std::endl; } else if(threadarray[1].get_id() == boost::this_thread::get_id()) { //Terminating the thread return 0; } else if(threadarray[2].get_id() == boost::this_thread::get_id()) { std::cout<<boost::this_thread::get_id()<<"\t is thread 3 with arg "<<someArg<<std::endl; } return 0; }
int main() {
threadarray[0] = boost::thread(t,5); threadarray[1] = boost::thread(t,6); threadarray[2] = boost::thread(t,7);
for(int i = 0; i <3;i++) { threadarray[i].join(); } system("pause"); return 0; }

Thanks for your meticulous observation :) so instead of just retyping lockguard inside all of if statements , one at the very beginning of the function in question would suffice right ? :)
Well, locking the whole thread function you actually prevent the threads from running in parallel. You could just lock the shared resource, copy it (if it's inexpensive), and release: lock_guard<mutex> locker(mutex); // copy id objects here to some local array locker.unlock(); // proceed.
int main() {
threadarray[0] = boost::thread(t,5); threadarray[1] = boost::thread(t,6); threadarray[2] = boost::thread(t,7);
You should lock the above as well, because when you're moving a thread object to threadarray, the thread function is already being runnning.

Well, locking the whole thread function you actually prevent the threads from running in parallel. You could just lock the shared resource, copy it (if it's inexpensive), and release: lock_guard<mutex> locker(mutex); // copy id objects here to some local array locker.unlock(); // proceed.
int main() {
threadarray[0] = boost::thread(t,5); threadarray[1] = boost::thread(t,6); threadarray[2] = boost::thread(t,7);
You should lock the above as well, because when you're moving a thread object to threadarray, the thread function is already being runnning.
i should lock that too? but those threads are somewhere else ! only main thread is doing the assignment! how would locking help main ? would locking pause all these threads ? and what do you mean by : //* copy id objects here to some local array* whats your meaning about id objects ? did you mean the thread id ? , whats the local array ? an array declared inside that function ? (would be shared among other threads too right? then whats the point? ) Thank you again for your help sir :)

i should lock that too? but those threads are somewhere else ! only main thread is doing the assignment!
a) the main thread modifies "threadarray" object; b) the other threads read "threadarray" object (technically speaking, they might modify it as well because of vector's operator[] nature). You should synchronize (a) and (b) - using mutex.
would locking pause all these threads ?
It will pause, if you do as follows: int main() { lock_guard<mutex> lock(mutex); threadarray[0] = boost::thread(t,5); threadarray[1] = boost::thread(t,6); threadarray[2] = boost::thread(t,7); lock.unlock(); //... } int t(int x) { lock_guard<mutex> lock(mutex); // access threadarray lock.unlock() //... } This way the thread function t() accesses threadarray only after it's filled in main().
and what do you mean by :
// copy id objects here to some local array whats your meaning about id objects ?
thread::get_id() and this_thread::get_id() return you thread::id instances: http://www.boost.org/doc/libs/1_49_0/doc/html/thread/thread_management.html#...
whats the local array ? an array declared inside that function ?
Yes.
(would be shared among other threads too right?
No. Local objects are not shared between threads.

Thank you very much sir , but how could possibly those threads modify the itemes in a vector using [] operator!! ? in my sample i just had them read a value using [] operator ! there is no assignment ! would you explain it abit more please ? thank you very much again :)

Thank you very much sir , but how could possibly those threads modify the itemes in a vector using [] operator!! ? in my sample i just had them read a value using [] operator ! there is no assignment !
You call a non-const overload of operator[], so theoretically it can change the vector (if it's not prohibited by the standard). Actually, even if it were the const overload, it could change some mutable internal object state (again, it's worth reading what the standard says about it), so I guess you can't treat the operator[] as a pure "reader". Anyway, in your case it's not so important, as you use the regular mutex, not shared_mutex.

Le 15/04/12 14:19, Master a écrit :
Hello all . i have been trying to selectively dispose a thread among some other threads , but so far i wasnt successful in finding a way to do it . suppose i have a simple function which identifies any threads which gets into it and if a specific one is located ,it is disposed . simply sth like this :
Hi,
#include <boost/signal.hpp> #include <iostream> #include <boost/thread.hpp> using namespace std; boost::thread threadarray[3];
int t(int x) { boost::id id(); Do you mean boost::thread::id? switch(boost::this_thread::get_id()) boost::thread::id can not be used in a switch. :( You can use if instead.
In addition the access to threadarray is not thread-safe, so you can not be sure it has been initialized as you could expect. You will need to protect it (read/write access) with a mutex :(
{ case threadarray[0].get_id(): cout<<"thread 1"; break; case threadarray[1].get_id(): *DISPOSE THIS THREAD or CHANGE OWNERSHITP, OR GET ANOTHER JOB TO IT , OR CHECK IF IT WAS SUCCESSFUL OR NOT*
Could you clarify what exactly do you want to do if this is important for you?
break; case threadarray[3].get_id(): cout<<"thread 3"; break; default: cout<<"default"; } return 0; }
int main() { boost::thread t1(t,5), t2(t,6),t3(t,7);
threadarray[0] = t1.move(); threadarray[1] = t2.move(); threadarray[2] = t3.move();
for(int i = 0; i <3;i++) { threadarray[i].join(); } system("pause"); }
i cant either use a switch statement to identify which thread im dealing with at the moment , nor can i find any means to keep track of my threads , and manage them in situations like this ( i already tried vector(boost::thread> my vect; and tries to use std::for_each(vect.begin(),vect.end(),somefunction_accepting boost::thread) , this doesnt work !! )
You need to use a move aware vector, e.f. boost::container::vector. If you don't have access to them use std::vector<thread*> threadarray; or boost::thread* threadarray[3]; Please, in the future, could you show what error have you getting, the platform, the version ,... when you say that your code doesn't work so that we can help you or improve the library if a bug is found?
any idea how i can achieve sth similar?
HTH, Vicente

none worked :( neither the boost::this_thread::get_id() is useable in a switch statement , nor the suggested use of boost::thread* or boost::container::vector<thread> . before i give the faulty source code of mine , i need to answer what exactly im after . see some of my friends are trying to learn boost , specially to work with its threading capabilities to use it in a project of theirs . they have no idea what boost is , or how these stuff work , so its on me , because unlike them i had a little experience with boost in a long past . so one of them asked me a question on a scenario where there is a function , which is reapeately creating new threads , and each thread execute a function with a unique request message , in the aforementioned function ( dispatcher lets say ) , he wants to see if he as a ability to distinguish between the coming threads , and altering them at any given moment , be it terminating them , or simply getting its Id for further management , again by management i mean , in other functions ( or objects methods ) the thread can be specified by its ID , for being recognized for being surveyed , or again being terminated or moved . and i also have another question , how do i send an argument to afunction with is goingto be used as packaged_task? it seems , i can only make packaged_task objects out of strucs! or classes! seems i cant even use functions at all! is it right ? i would appreciate an explanation on this matter too please . and now here is the source : i am on windows 7 sp1 - 32bit - Visual studio 2010 .
#include <boost/signal.hpp> #include <iostream> #include <boost/thread.hpp> using namespace std;
boost::thread* threadarray[3];
int t(int x) { switch(boost::this_thread::get_id()) { case threadarray[0].get_id(): cout<<"thread 1"; break; case threadarray[1].get_id(): //DISPOSE THIS THREAD or CHANGE OWNERSHITP, OR GET ANOTHER JOB TO IT , OR CHECK IF IT WAS SUCCESSFUL OR NOT cout<<"thread 2"; break; case threadarray[3].get_id(): cout<<"thread 3"; break; default: cout<<"default"; } return 0; }
int main() { boost::thread t1(t,5), t2(t,6),t3(t,7);
threadarray[0] = t1.move(); threadarray[1] = t2.move(); threadarray[2] = t3.move();
for(int i = 0; i <3;i++) { threadarray[i].join(); } system("pause"); }
and these are the errors:
Error 1 error C2450: switch expression of type 'boost::thread::id' is illegal c:\users\master\documents\visual studio 2010\projects\boost example\boost example\mb.cpp 61 1 Boost Example Error 2 error C2228: left of '.get_id' must have class/struct/union c:\users\master\documents\visual studio 2010\projects\boost example\boost example\mb.cpp 63 1 Boost Example Error 3 error C2046: illegal case c:\users\master\documents\visual studio 2010\projects\boost example\boost example\mb.cpp 63 1 Boost Example Error 4 error C2228: left of '.get_id' must have class/struct/union c:\users\master\documents\visual studio 2010\projects\boost example\boost example\mb.cpp 66 1 Boost Example Error 5 error C2046: illegal case c:\users\master\documents\visual studio 2010\projects\boost example\boost example\mb.cpp 66 1 Boost Example Error 6 error C2228: left of '.get_id' must have class/struct/union c:\users\master\documents\visual studio 2010\projects\boost example\boost example\mb.cpp 70 1 Boost Example Error 7 error C2046: illegal case c:\users\master\documents\visual studio 2010\projects\boost example\boost example\mb.cpp 70 1 Boost Example Warning 8 warning C4065: switch statement contains 'default' but no 'case' labels c:\users\master\documents\visual studio 2010\projects\boost example\boost example\mb.cpp 75 1 Boost Example Error 9 error C2440: '=' : cannot convert from 'boost::thread' to 'boost::thread *' c:\users\master\documents\visual studio 2010\projects\boost example\boost example\mb.cpp 83 1 Boost Example Error 10 error C2440: '=' : cannot convert from 'boost::thread' to 'boost::thread *' c:\users\master\documents\visual studio 2010\projects\boost example\boost example\mb.cpp 84 1 Boost Example Error 11 error C2440: '=' : cannot convert from 'boost::thread' to 'boost::thread *' c:\users\master\documents\visual studio 2010\projects\boost example\boost example\mb.cpp 85 1 Boost Example Error 12 error C2228: left of '.join' must have class/struct/union c:\users\master\documents\visual studio 2010\projects\boost example\boost example\mb.cpp 89 1 Boost Example 13 IntelliSense: expression must have integral or enum type c:\users\master\documents\visual studio 2010\projects\boost example\boost example\mb.cpp 11 9 Boost Example 14 IntelliSense: expression must have class type c:\users\master\documents\visual studio 2010\projects\boost example\boost example\mb.cpp 13 7 Boost Example 15 IntelliSense: expression must have class type c:\users\master\documents\visual studio 2010\projects\boost example\boost example\mb.cpp 16 8 Boost Example 16 IntelliSense: expression must have class type c:\users\master\documents\visual studio 2010\projects\boost example\boost example\mb.cpp 20 8 Boost Example 17 IntelliSense: no suitable conversion function from "boost::thread" to "boost::thread *" exists c:\users\master\documents\visual studio 2010\projects\boost example\boost example\mb.cpp 33 19 Boost Example 18 IntelliSense: no suitable conversion function from "boost::thread" to "boost::thread *" exists c:\users\master\documents\visual studio 2010\projects\boost example\boost example\mb.cpp 34 19 Boost Example 19 IntelliSense: no suitable conversion function from "boost::thread" to "boost::thread *" exists c:\users\master\documents\visual studio 2010\projects\boost example\boost example\mb.cpp 35 19 Boost Example 20 IntelliSense: expression must have class type c:\users\master\documents\visual studio 2010\projects\boost example\boost example\mb.cpp 39 3 Boost Example
participants (3)
-
Igor R
-
Master
-
Vicente J. Botet Escriba