How to access the Accepted and Close Event of QDialogbox - c++

i have a Qdialogbox and in this qdialogbox i have a thread(named thread3) which executes Print_Descendants_key(IUIAutomation* pUIAutomation, IUIAutomationElement* pParent, int indent) function,
in this thread3.
so in my Accepted event(when i click okay in buttonbox) and closeEvent of dialog box, i want to quit/terminate this thread3. How can i do that ?
probably something like this ??
void KeyComd::closeEvent(QCloseEvent* event)
{
std::terminate();
thread3.terminate(); ??
}
void KeyComd::accepted()
{
std::terminate();
}
for reference here is my QDialog code
#include "KeyComd.h"
#include "ui_KeyComd.h"
#include <QtCore>
#include <QtGui>
#include <vector>
#include<QDebug>
#include "ExecutionContext.h"
#include "XMLParser.h"
#include "Logger.h"
#include "BlockCommand.h"
#include "UIAElementUtils.h"
ExecutionContext exc;
QStringList refreshed_elements;
KeyComd::KeyComd(QWidget *parent)
: QDialog(parent)
{
ui.setupUi(this);
HRESULT hr = exc.init();
}
KeyComd::~KeyComd()
{
}
void KeyComd::on_showbutton_clicked()
{
ui.elements_listwidget->clear();
desktop_elements.clear();
std::thread thread3(&KeyComd::Print_step, this); // Here it calls a thread, because of this thread ,the execution of "Print_Descendants_key" function happens in a separate thread from main thread
thread3.detach();
}
void KeyComd::Print_step()
{
Print_Descendants_key(exc.pUIAutomation, nullptr, 0);
}
void KeyComd::Print_Descendants_key(IUIAutomation* pUIAutomation, IUIAutomationElement* pParent, int indent)
{
///Function which appends 1000 list-items in a QListWidget called "elements_listwidget" in my QDialog.
}

There's no good way to force terminate a single thread- see this related SO answer. However, what you can do is signal that thread to end itself. Here's another relevant SO question, but also wrote a quick example demonstrating the technique with an atomic_bool:
#include <iostream>
#include <thread>
#include <atomic>
#include <chrono>
std::atomic_bool terminateThreads; // Atomic for setting and reading safely across threads
void runInfinitely() {
while (!terminateThreads) {
// Do some work
std::cout << "Running infinite thread..." << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(150));
}
std::cout << "Terminated thread" << std::endl;
}
int main() {
// Create your thread as you normally would
std::thread infThread(runInfinitely);
// Whatever else you like to do...
std::this_thread::sleep_for(std::chrono::seconds(1));
// Once you're ready to end it, just set the atomic flag as appropriate
terminateThreads = true;
infThread.join(); // Optional in context of this SO question
std::cout << "End of main" << std::endl;
return 0;
}
However, going by that comment in KeyComd::Print_Descendants_key it seems like the function has a finite length and thus will naturally finish + clean itself up (relevant SO answer here). Thus, if you're fine waiting until the thread's function naturally ends, then you're not required to "terminate" or clean up the thread manually at all.

Related

As i have made the flag volatile at some point it value of flag should change. But it is waiting infinitely on t thread only

#include <iostream>
#include<thread>
#include <initializer_list>
#include <vector>
#include <future>
#include <time.h>
using namespace std;
class Gadget{
public:
Gadget(){
flag_ = false;
cout<<"Creating new Gadgets"<<endl;
}
void wait(){
while(flag_==false){
cout<<"waiting here...."<<endl;
this_thread::sleep_for(chrono::milliseconds(1000));
}
}
void wake(){
flag_ = true;
}
private:
volatile bool flag_;
};
I am trying to make two threads and one thread will sleep for 1 sec after checking the flag value. As i have made flag volatile it should change at some point. But the program is waiting infinitely.
int main() {
Gadget g;
thread t(&Gadget::wait,g);
thread s(&Gadget::wake,g);
t.join();
s.join();
cout<<"Ending the program "<<endl;
return 0;
}
volatile isn't for variables that are changed by the program itself. It's for variables that changes outside the program's control - like if it's directly connected to hardware.
Your main problem is however that you pass g by value so the two threads are working on different copies of your original g.
So, change to
std::atomic<bool> flag_;
and
thread t(&Gadget::wait, &g);
thread s(&Gadget::wake, &g);
Also worth mentioning: The two methods will not necessarily run in the order you start them, so waiting here.... may or may not show up.
Edit:
As mentioned in the comments: When waiting for a condition you should usually use a std::condition_variable. I've made an example of how that could look. I've also moved the starting of the threads into Gadget which makes it more obvious which object the thread is working on.
#include <chrono>
#include <condition_variable>
#include <iostream>
#include <mutex>
#include <thread>
#include <vector>
class Gadget {
public:
Gadget() { std::cout << "Creating new Gadget\n"; }
// new interface for starting threads
std::thread start_wait() { return std::thread(&Gadget::wait, this); }
std::thread start_wake() { return std::thread(&Gadget::wake, this); }
private:
void wait() {
std::unique_lock<std::mutex> ul(mutex_);
std::cout << "wait: waiting here...\n";
// Read about "spurious wakeup" to understand the below:
while(not flag_) cond_.wait(ul);
// or:
// cond_.wait(ul, [this] { return flag_; });
std::cout << "wait: done\n";
}
void wake() {
// simulate some work being done for awhile
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
{ // lock context start
std::lock_guard<std::mutex> lg(mutex_);
flag_ = true;
std::cout << "wake: notifying the waiting threads\n";
} // lock context end
// notify all waiting threads
cond_.notify_all();
}
std::condition_variable cond_;
std::mutex mutex_;
bool flag_ = false; // now guarded by a mutex instead
};
int main() {
Gadget g;
// start some waiting threads
std::vector<std::thread> threads(16);
for(auto& th : threads) th = g.start_wait();
// and one that wakes them up
auto th_wake = g.start_wake();
for(auto& th : threads) th.join();
th_wake.join();
std::cout << "Ending the program\n";
}

How to terminate a function call after a timeout?

Let's say I have a foo() function. I want it to run in, for example, 5 seconds, after that, it has to be cancelled and continues to do the rest of the program.
Code snippets:
int main() {
// Blah blah
foo(); // Running in 5 sec only
// After 5 sec, came here and finished
}
References: After a while searching on StackOverflow, I found this is what I need but written in python: Timeout on a function call.
signal.h and unistd.h can be related.
This is possible with threads. Since C++20, it will be fairly simple:
{
std::jthread t([](std::stop_token stoken) {
while(!stoken.stop_requested()) {
// do things that are not infinite, or are interruptible
}
});
using namespace std::chrono_literals;
std::this_thread::sleep_for(5s);
}
Note that many interactions with the operating system cause the process to be "blocked". An example of such is the POSIX function listen, which waits for incoming connections. If the thread is blocked, then it will not be able to proceed to the next iteration.
Unfortunately, the C++ standard doesn't specify whether such platform specific calls should be interrupted by request to stop or not. You need to use platform specific methods to make sure that happens. Typically, signals can be configured to interrupt blocking system calls. In case of listen, an option is to connect to the waiting socket.
There is no way to do that uniformly in C++. There are ways to do this with some degree of success when you use OS specific APIs, however it all becomes extremely cumbersome.
The basic idea which you can use in *nix is a combination of alarm() system call and setjmp/longjmp C function.
A (pseudo) code:
std::jmp_buf jump_buffer;
void alarm_handle(int ) {
longjmp(jump_buffer);
}
int main() {
signal(SIGALRM, alarm_handle);
alarm(5);
if (setjmp(jump_buffer)) {
foo(); // Running in 5 sec only
} else {
// After 5 sec, came here and finished
// if we are here, foo timed out
}
}
This all is extremely fragile and shaky (i.e. long jumps do not place nicely with C++ objects lifetime), but if you know what you are doing this might work.
Perfectly standard C++11
#include <iostream>
#include <thread> // std::this_thread::sleep_for
#include <chrono> // std::chrono::seconds
using namespace std;
// stop flag
bool stopfoo;
// function to run until stopped
void foo()
{
while( ! stopfoo )
{
// replace with something useful
std::this_thread::sleep_for (std::chrono::seconds(1));
std::cout << "still working!\n";
}
std::cout "stopped\n";
}
// function to call a top after 5 seconds
void timer()
{
std::this_thread::sleep_for (std::chrono::seconds( 5 ));
stopfoo = true;
}
int main()
{
// initialize stop flag
stopfoo = false;
// start timer in its own thread
std::thread t (timer);
// start worker in main thread
foo();
return 0;
}
Here is the same thing with a thread safe stop flag ( not really neccessary, but good practice for more complex cases )
#include <iostream>
#include <thread> // std::this_thread::sleep_for
#include <chrono> // std::chrono::seconds
#include <mutex>
using namespace std;
class cFlagThreadSafe
{
public:
void set()
{
lock_guard<mutex> l(myMtx);
myFlag = true;
}
void unset()
{
lock_guard<mutex> l(myMtx);
myFlag = false;
}
bool get()
{
lock_guard<mutex> l(myMtx);
return myFlag;
}
private:
bool myFlag;
mutex myMtx;
};
// stop flag
cFlagThreadSafe stopfoo;
// function to run until stopped
void foo()
{
while( ! stopfoo.get() )
{
// replace with something useful
this_thread::sleep_for (std::chrono::seconds(1));
cout << "still working!\n";
}
cout << "stopped\n";
}
// function to call a top after 5 seconds
void timer()
{
this_thread::sleep_for (chrono::seconds( 5 ));
stopfoo.set();
}
int main()
{
// initialize stop flag
stopfoo.unset();
// start timer in its own thread
thread t (timer);
// start worker in main thread
foo();
t.join();
return 0;
}
And if it is OK to do everything in the main thread, things can be greatly simplified.
#include <iostream>
#include <thread> // std::this_thread::sleep_for
#include <chrono> // std::chrono::seconds
using namespace std;
void foo()
{
auto t1 = chrono::steady_clock ::now();
while( chrono::duration_cast<chrono::seconds>(
chrono::steady_clock ::now() - t1 ).count() < 5 )
{
// replace with something useful
this_thread::sleep_for (std::chrono::seconds(1));
cout << "still working!\n";
}
cout << "stopped\n";
}
int main()
{
// start worker in main thread
foo();
return 0;
}

::write() and ::read() has not been declared error. Qt5 UNIX signal handling

So, I'm trying to follow the tutorial given
http://qt-project.org/doc/qt-5/unix-signals.html
to catch UNIX/Linux signals and do something Qt related when triggered by them.
It's on the qtDocs, so I consider it legit.
My present code is as follows:
mydaemon.cpp
#include "mydaemon.h"
#include <QDebug>
#include <QObject>
#include <QSocketNotifier>
#include <csignal>
#include <sys/socket.h>
#include <iostream>
#include <stdio.h>
#include <signal.h>
//needed to not get an undefined reference to static members
int MyDaemon::sighupFd[2];
int MyDaemon::sigtermFd[2];
MyDaemon::MyDaemon(QObject *parent)
: QObject(parent)
{
if (::socketpair(AF_UNIX, SOCK_STREAM, 0, sighupFd))
qFatal("Couldn't create HUP socketpair");
if (::socketpair(AF_UNIX, SOCK_STREAM, 0, sigtermFd))
qFatal("Couldn't create TERM socketpair");
snHup = new QSocketNotifier(sighupFd[1], QSocketNotifier::Read, this);
connect(snHup, SIGNAL(activated(int)), this, SLOT(handleSigHup()));
snTerm = new QSocketNotifier(sigtermFd[1], QSocketNotifier::Read, this);
connect(snTerm, SIGNAL(activated(int)), this, SLOT(handleSigTerm()));
}
MyDaemon::~MyDaemon() {}
void MyDaemon::hupSignalHandler(int)
{
qDebug() << "signal hup";
char a = '1';
::write(sighupFd[0], &a, sizeof(a));
}
void MyDaemon::termSignalHandler(int)
{
qDebug() << "signal term";
char a = '1';
::write(sigtermFd[0], &a, sizeof(a));
}
void MyDaemon::handleSigTerm()
{
snTerm->setEnabled(false);
char tmp;
::read(sigtermFd[1], &tmp, sizeof(tmp));
// do Qt stuff
qDebug() << "MyDaemon::handleSigTerm";
snTerm->setEnabled(true);
}
void MyDaemon::handleSigHup()
{
snHup->setEnabled(false);
char tmp;
::read(sighupFd[1], &tmp, sizeof(tmp));
// do Qt stuff
qDebug() << "MyDaemon::handleSigHup";
snHup->setEnabled(true);
}
Now, when I create my C++ class, and try to build, it gives the errors such as,
/home/xxxx/Documents/Qt Projects/mainScreen/mydaemon.cpp:-1: In static member function 'static void MyDaemon::termSignalHandler(int)':
/home/xxxx/Documents/Qt Projects/mainScreen/mydaemon.cpp:49: error: '::write' has not been declared
::write(sigtermFd[0], &a, sizeof(a));
^
and so on, for all instances of the ::read() or ::write() calls. I'm not sure what I'm doing wrong, I'm grateful for any help :)
If you are using "basic" Unix functions, you need to use
#include <unistd.h>
This will give you read, write, open, close, sleep, usleep and many other functions.

End two alarm signals in Unix and count SIGINT

#include <iostream>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
using namespace std;
int count = 0;
void alarm2(int signo)
{
cout << count;
}
void alarm1(int signo)
{
signal(SIGALRM, alarm2);
cout << "ctrl+C";
alarm(10);
sleep(10);
}
int main()
{
signal(SIGALRM, alarm1);
alarm(3);
sleep(5);
}
I want that after 3 seconds I get the message "ctrl+C" and then another alarm set for 10 seconds; after that I should get the value of count. But when I run after just 10 sec I get "ctrl+C" and the value of count.
In your example you made many, many mistakes.
First of all look at documentation about which function is safe to call from
signal handlers:
https://www.securecoding.cert.org/confluence/display/seccode/SIG30-C.+Call+only+asynchronous-safe+functions+within+signal+handlers
Of course functions that can allocate memory is not safe to call, because of it is not safe to call malloc.
Because of it is not right to call printf or std::ostream::opeartor<< (std::cout <<) in signal handler.
Second, in documentation (type man 3 sleep) clearly written it is not safe mix sleep and alarm,
Third you not wait enough in main function, so it can exit before the second alarm handler run.
Here is how it can be done:
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
volatile sig_atomic_t done = 0;
void alarm2(int signo)
{
write(STDOUT_FILENO, "alarm2\n", sizeof("alarm2\n") - 1);
done = 1;
}
void alarm1(int signo)
{
signal(SIGALRM, alarm2);
write(STDOUT_FILENO, "ctrl+C\n", sizeof("ctrl+C\n") - 1);
alarm(10);
}
int main()
{
signal(SIGALRM, alarm1);
alarm(3);
while (done == 0)
sleep(1); //sleep can be wake up by alarm signal, so check flag
}
Add "<< endl;" to all your cout statements and try again.

Trying to prevent race conditions with pselect(), but signal won't interupt

I am currently trying to implement a server in C++ using sockets. I am trying to prevent race conditions by blocking the SIGINT signal until it is stuck in the blocking pselect. From there, it should be exiting, changing my loop variable, and then quitting the thread. From my attempts at getting this working, it appears that it reaches the pselect(), but it does not get interrupted using my code. Any help is appreciated.
Listener.h:
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
class CListener
{
public:
CListener();
void quitListener(void);
private:
void* InitListener(void);
static void* StartListenerThread(void* context);
static bool mbListening;
pthread_t mtThreadID;
};
Listener.cpp
#include <iostream>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <pthread.h>
#include <signal.h>
#include <errno.h>
#include "Listener.h"
bool CListener::mbListening = true;
CListener::CListener()
{
mbListening = true;
mtThreadID = 0;
pthread_create(&mtThreadID, NULL, &CListener::StartListenerThread, this);
}
void* CListener::StartListenerThread(void* context)
{
return ((CListener*)context)->InitListener();
}
void* CListener::InitListener()
{
sigset_t tSignalSet;
sigset_t tOriginalSignalSet;
sigemptyset(&tSignalSet);
sigaddset(&tSignalSet, SIGINT);
sigprocmask(SIG_BLOCK, &tSignalSet, &tOriginalSignalSet);
FD_ZERO(&tConnectionSet);
FD_SET(0, &tConnectionSet);
while(mbListening)
{
tSelectSet = tConnectionSet;
std::cout << "Reached pselect\n";
nReadyConnections = pselect(nSelectSocket+1, &tSelectSet,
NULL, NULL, NULL, &tOriginalSignalSet);
std::cout << "Broke out of pselect\n";
if(nReadyConnections < 0 && errno == EINTR)
{
mbListening = false;
}
}
pthread_exit(NULL);
return NULL;
}
void CListener::quitListener()
{
raise(SIGINT);
}
As long as I copied everything correctly fingers crossed you should just be able to run:
CListener tListener = CListener();
usleep(20000);
tListener.quitListener();
and the outputs should be displayed in terminal. My end goal is that I can allow for pselect to be interrupted without breaking any processing that may come after and allowing the thread to close gracefully. (blocking at pselect > recieve SIGINT > interupt pselect > return to loop > finish up and exit)
I've solved my own problem. Since I am generating a thread, I needed to add functions that allow for that, as well as adding a signal handler, like shown below.
void CListener::quitListener()
{
pthread_kill(mtThreadID,SIGINT);
}
void CListener::installSIGINTHandler()
{
signal(SIGINT, CListener::SIGINTHandler);
}
void CListener::SIGINTHandler(int signo)
{
mbListening = false;
}
And needed to change the sig mask setup to this:
pthread_sigmask(SIG_BLOCK, &tSignalSet, &tOriginalSignalSet);