I use a 3rd-party-library (dcerpc) for my application being a rpc server.
Let's say the 3rd party function are in the namespace third.
I call third::listen in a thread, in order to listen for incoming requests.
"Third" provides all the mechanisms to interrupt this listen and properly exit the thread, but either it doesn't work, or I don't do it the correct way.
I first try everything with the library tools (demo sample, mail-list, browse the source code to understand...) but with no success.
So I try an alternative: violently kill the listening thread.
But third::listen has no cancellation point, I guess.
So this code (I simulate third::listen with listen function above):
void* listen(void*)
{
cout << "listening for calls...." << endl;
while (true) {}
printf ("Server stoppped listening\n");
return 0;
}
int main()
{
pthread_t thread = 0;
int res = pthread_create(&thread, 0, listen, 0);
cout << "pthread_create res: " << res << endl;
sleep(1);
bool isThreadRunning = (pthread_tryjoin_np(thread, 0) != 0);
cout << "Thread is running: " << isThreadRunning << endl;
res = pthread_cancel(thread);
cout << "pthread_cancel res: " << res << endl;
sleep(1);
isThreadRunning = (pthread_tryjoin_np(thread, 0) != 0);
cout << "Thread is running: " << isThreadRunning << endl;
res = pthread_join(thread, 0);
cout << "pthread_join res: " << res << endl;
return 0;
}
will output:
pthread_create res: 0
listening for calls....
Thread is running: 1
pthread_cancel res: 0
Thread is running: 1
and pthread_join(thread, 0) blocks (logic because no cancellation point).
My question: how to kill this thread !!
I tried with signals, but it stops my whole process, not only the thread.
My last try will be to isolate the listening in a dedicated fork process, but in my project context, it's really a pain to fork (that's another story).
Thanks a lot for any help.
Nicolas.
Whether a thread can be cancelled depends on its cancellation state and type. The default state is enabled. So that's fine. But the default type is deferred. That means when you send the thread a cancellation request, it's deferred until it reaches a cancellation point. Since your thread doesn't do anything in the empty loop, it doesn't reach a cancellation point at all. Hence, it doesn't respond to pthread_cancel().
You can set the cancellation type of the thread to PTHREAD_CANCEL_ASYNCHRONOUS which will typically make the thread exit. Call
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, 0);
before the loop.
Or you can call one of the functions that's a cancellation point. For example, do fflush(stdout); inside the loop.
POSIX list a number of functions as cancellation point. See cancellation points for such a list.
I can't make any comment on the "3rd party" library that doesn't respond to exiting threads with the limited information you have given.
Related
I am trying to create a very threaded simple producer consumer toy implementation, but I'm running into a strange issue where the same consumer thread keeps getting rescheduled over and over again even though I am yielding control.
Here is an abridged version of my code. The Main method is simple , I start one producer and two consumer threads. I join to the producer thread and detach the two consumer threads. A getchar at the end of the main method keeps the program from exiting.
std::vector<int> UnprocessedValues;
std::vector<int> ProcessedValues;
std::mutex unprocessed_mutex;
void AddUnprocessedValue()
{
for (int i = 0; i <= 1000; ++i)
{
{
std::lock_guard<std::mutex> guard(unprocessed_mutex);
UnprocessedValues.push_back(i);
std::cout << "Thread id : " << std::this_thread::get_id() << " ";
printf("Unprocessed value added %i \n", UnprocessedValues.back());
}
}
}
void ProcessCurrentValue()
{
while (true)
{
unprocessed_mutex.lock();
if (UnprocessedValues.empty())
{
std::cout << "Thread id : " << std::this_thread::get_id() << " ";
printf("is waiting for values \n");
unprocessed_mutex.unlock();
std::this_thread::yield();
}
else
{
// Process value
unprocessed_mutex.unlock();
}
}
}
I expect that when there are no values present for consumers, they will both yield and end up giving the producer a chance to produce more.
In practice I see a single consumer getting stuck on waiting for values. Eventually the program rights itself, but something is obviously wrong.
If I was seeing the two consumers print that they are waiting in alternate, I would think that somehow the producer is getting shafted by the two consumers taking turns, but the actual result is that the same thread keeps getting rescheduled even though it just yielded.
Finally, when I change the if case from
if (UnprocessedValues.empty())
{
std::cout << "Thread id : " << std::this_thread::get_id() << " ";
printf("is waiting for values \n");
unprocessed_mutex.unlock();
std::this_thread::yield();
}
to
if (UnprocessedValues.empty())
{
unprocessed_mutex.unlock();
std::this_thread::yield();
std::cout << "Thread id : " << std::this_thread::get_id() << " ";
printf("is waiting for values \n");
}
I never see a busy wait. I realize that I could use a condition variable to fix this problem and I have already seen that using a small sleep instead of a yield works. I am just trying to understand why the yield would not work.
std::mutex MTX;
bool ExitThread = false;
//This function is running in a separate thread
//for constantly trying to connect to a server in a non blocking manner
void ClientConnectingLoop(sf::TcpSocket* client, std::string ipAddress,
unsigned short port)
{
std::cout << "Start" << std::endl;
MTX.lock();
std::cout << "Start2" << std::endl;
while(client->connect(ipAddress, port) != sf::Socket::Status::Done &&
!ExitThread)
{
}
std::cout << "Done" << std::endl;
MTX.unlock();
}
int main()
{
//Code for setting ipaddress and port is abstracted.
std::string ipAddress;
unsigned short port;
//Setup socket
sf::TcpSocket clientSocket;
clientSocket.setBlocking(false);
//Connect to server
std::thread ClientConnectThread(ClientConnectingLoop, &clientSocket, ipAddress, port);
std::cout << "Connecting to server......" << std::endl;
//Wait until it finishes executing, code inside this loop is abstracted
while(!ClientConnectThread.joinable())
{
}
//The thread is finished executing.
if(ClientConnectThread.joinable())
{
std::cout << "Joinable returned true" << std::endl;
ClientConnectThread.join();
}
//........
}
The problem comes to that the thread returns joinable (true) despite the loop in the thread is still running.
So that means the console outputs "Connecting to server......" => "Start" => "Start2" => "Joinable returned true" but "Done" should be printed after "Start2" unless I misunderstood joinable function
I am still fairly new to c++ and SFML, please be kind when pointing out any mistakes.
Quoting directly from cppreference.com
std::thread::joinable
Checks if the thread object identifies an active thread of execution. Specifically, returns true if get_id() != std::thread::id(). So a default constructed thread is not 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.
Based on this, the idea of a joinable thread is different. A thread is always joinable except if has been default-constructed and has not been assigned to a function/method to run or if you have already called the thread.join() method on it.
An rather simple solution to the problem at hand would be to use some multithreading-aware locking construct such as std::atomic or void futures to communicate the result as suggested in the Effective Modern C++ book of Scott Meyers
I have parent process, that have to create few children processes. Best way I found is using fork + execl. But then parent process need to know if execl of concrete child fails or not, and I don't know how to implement that.
int pid = fork();
if (pid < 0) {
std::cout << "ERROR on fork." << std::endl;
} if (pid == 0) {
execl("/my/program/full/path", (char *)NULL);
exit(1);
}
else {
if (/*child's process execl fails*/) {
std::cout << "it failed" << std::endl
} else {
std::cout << "child born" << std::endl
}
}
I think this idea is not good:
int status(0);
sleep(100);
int res = waitpid(pid, &status, WNOHANG);
if (res < 0 && errno == 10) {
std::cout << "it failed" << std::endl
} else {
std::cout << "child born" << std::endl
}
because it's not good to hope that child process will die after 100 milliseconds, I want to know that for sure as only that will happens.
I also think that creation of shared_memory or special pipe connection for such check is a Cannon against Bees.
There have to be simple solution for that, that I just didn't found yet.
What is the best way to achieve that?
As a general solution you can register signal handler (SIGUSR1) in the parent using sigaction().
In a child: unregister signal handler, if execl() call failed you need to send SIGUSR1 to the parent.
In the parent: Every child pid we will store in std::set. When all childs are created you just create a separate thread for tracking childs. In the thread function just call wait() and remove pid from the set. Another way to listen SIGCHLD signal (but it will lead to more complex solution, so if spawn another thread is an option I'd use thread).
When the set is empty we have done.
I have a function which has to search all pcs in the network and look for responses:
DLL void get_remote_ip(void)
{
initWSA();
if(create_Sockets() == INVALID_SOCKET)
{
std::cerr << "Socket Error\n";
return;
};
initiate_TXRX_variables();
boost::asio::io_service io_service;
udp_server_search server(io_service);
std::cout << "No crash till here\n";
boost::thread thread_1 = boost::thread(ultra_spam_network_udp);
boost::asio::deadline_timer dt1 = boost::asio::deadline_timer(io_service);
boost::thread thread_2(boost::bind(&boost::asio::io_service::run, &io_service));
dt1.expires_from_now(boost::posix_time::milliseconds(2000));
dt1.wait();
//ip_adr_ccd = server.return_ip(0);
if(ip_adr_ccd != "localhost" && ip_adr_daisy != "localhost")
{
std::cout << "Remote IP of CCD is: " << ip_adr_ccd << '\n';//For debug
std::cout << "Remote IP of TERS is: " << ip_adr_daisy << '\n'; //For debug
}
else
std::cout << "No new remote ips found\n";
//std::cout << Use << '\n';
//thread_1.join();
}
When I call this function, my program crashes sometimes without telling me why, it just tells me "Exception error in <hex-address>". Where is my bug? Is it possible that one thread tries to join, but the other one has not finished now (which can be possible because the errors are quite random and are killing the std::cout-output of the main thread within writing)?
Thank you!
I found my mistake, I have to stop io_service first and then call thread_2.join(), otherwise my thread_2 is crashing.
You don't seem to stop the io_service in a clean way. io_serice::run blocks while there are ramining handlers to be dispatched. My guess is that your udp_server_search causes an endless queueing of handlers. So either your join never finishes because it has to wait for the run() to return which never happens, or if you comment it out, leaving get_remote_ip will destroy the io_service while in thread_2 the run method continues to be executed on a now destroyed object.
What could solve your problem (besides from breaking the endless queue on the server) is manually stopping the ioservice:
boost::thread thread_2( [&]{io_service.run();} );
//do stuff, wait for the timer etc...
io_service.stop(); //run should return as soon as possible
thread_2.join(); //clean finishing of the service.
I am working in a C++ DLL module where I need to perform a task for every X min independently. I tried to create a thread for the task but my main program which creates threads will also keep waiting for the child thread(s) to complete.
Could someone please help me how to create a separate process (Please provide sample code if possible) independent of main program and do the Task?
The process should take a function and run the code present in function for every X min.
EDIT:
void test(void *param)
{
cout << "In thread function" << endl;
Sleep(1000); // sleep for 1 second
cout << "Thread function ends" << endl;
_endthread();
}
int main()
{
HANDLE hThread;
cout << "Starting thread" << endl;
cout << (hThread = (HANDLE)_beginthread(test,0,NULL));
WaitForSingleObject( hThread, INFINITE );
cout << "Main ends" << endl;
return 0;
}
WaitForSingleObject() will block main until the thread completes. If you want to run some stuff periodically from the thread function test() you'll need to put a loop there. Best with some condition to trigger ending the thread function from main() when exiting. You shouldn't call WaitForSingleObject() before you want to exit the main() method. Thus you'll have the test() method running asynchonously.
bool endThread = false;
void test(void *param)
{
cout << "In thread function" << endl;
while(!endThread)
{
Sleep(1000); // sleep for 1 second
}
cout << "Thread function ends" << endl;
_endthread();
}
int main()
{
HANDLE hThread;
cout << "Starting thread" << endl;
cout << (hThread = (HANDLE)_beginthread(test,0,NULL));
// Do any other stuff without waiting for the thread to end
// ...
endThread = true;
WaitForSingleObject( hThread, INFINITE );
cout << "Main ends" << endl;
return 0;
}
Note that you might need to synchronize access to the endThread variable properly using a mutex or similar, the sample should just show the principle.
UPDATE:
In case you want to exit main() before the thread ends, you cannot use threads at all.
You'll need to create an independent child process as I had mentioned in my 1st comment. Lookup for the fork() and exec() functions to do this (there might be specific WinAPI methods for these also, I don't know about).