How to trigger an event when thread completes its work [closed] - c++

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
Use case: Created thread pool in C++ and assigned the work to all the threads. I want to trigger an event when thread from threadpool completes its work.
But I don't know how to trigger an event when thread from thread pool completes its work.
Example:
void ThreadPoolImpl::InitThreadPool(){
pool = CreateThreadpool(NULL);
if (pool == NULL)
{
//Log("Could not create a thread pool!");
return;
}
InitializeThreadpoolEnvironment(&environment);
cleanupGroup = CreateThreadpoolCleanupGroup();
if (cleanupGroup == NULL)
{
//Log("Could not create a thread pool cleanup group!");
}
SetThreadpoolCallbackPool(&environment, pool);
SetThreadpoolCallbackCleanupGroup(&environment, cleanupGroup, NULL);}
void ThreadPoolImpl::RunThreads(int const iThreadCount)
{
dwThreadCount = iThreadCount;
if (dwThreadCount == 0)
{
dwThreadCount = DEFAULT_THREAD_COUNT;
}
SetThreadpoolThreadMaximum(pool, dwThreadCount);
SetThreadpoolThreadMinimum(pool, MIN_THREAD_COUNT);
work = CreateThreadpoolWork(workcallback,NULL,&environment);
if (NULL == work) {
_tprintf(_T("CreateThreadpoolWork failed. LastError: %u\n"),
GetLastError());
}
SubmitThreadpoolWork(work);//Want to trigger an event for each thread in thread pool
}
Help me to solve this.
Thanks in advance.

Use a condition_variable for each thread.

Related

Monitor a program and restart it on crash [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I have a program which crashs sometimes. On such occasion my program should restart itself. But while killing it through Task Manager it should end.
I have create Monitor program which monitors actual program and restart it on crash.
I have do this job using signals that are sent the actual program to terminate it.
I am using Windows OS.
That is I need to intercept the signal sent to actual program in my monitor program
A process monitor should do the following:
Create the main process, and thereby obtain a handle to that process.
Wait for that handle to become signaled, for instance with WaitForSingleObject, which indicates that the process has terminated.
Restart the process, obtaining a new process handle, and then go to 2.
You should arrange that the monitor program always creates the main process and that both are in a job object that is configured for child processes to be terminated when the parent terminates. Then when you wish to terminate the program, you simply terminate the monitor. The job object then ensures that the child program is also terminated.
If possible though, you should fix your program so that it does not crash.
Let's ignore your question for a moment, and address the problem instead. You are looking for a way to restart your application on abnormal exit, but still retain the ability, to terminate the application (either through its GUI or Task Manager).
Windows offers Application Recovery and Restart for this. It is the infrastructure built into the system, that allows you to register an application for restart in case of an unhandled exception (informally called a crash).
of course you need fix your app, for it not crashed. only this is good solution. however formally you can do next (bad)
void Ep()
{
// tag by * in begin of CommandLine
PWSTR CommandLine = GetCommandLine();
if (!CommandLine || *CommandLine != '*')
{
// monitor case
WCHAR FileName[MAX_PATH];
if (ULONG n = GetModuleFileName(0, FileName, RTL_NUMBER_OF(FileName)))
{
if (n < MAX_PATH)
{
PROCESS_INFORMATION pi;
STARTUPINFO si = { sizeof(si) };
PWSTR newCommandLine = (PWSTR)alloca((wcslen(CommandLine) + 2)*sizeof(WCHAR));
*newCommandLine = '*';
wcscpy(newCommandLine + 1, CommandLine);
// monitor and restart self in loop
BOOL bRestart;
do
{
bRestart = FALSE;
if (CreateProcessW(FileName, newCommandLine, 0, 0, 0, 0, 0, 0, &si, &pi))
{
CloseHandle(pi.hThread);
WaitForSingleObject(pi.hProcess, INFINITE);
ULONG exitcode;
bRestart = GetExitCodeProcess(pi.hProcess, &exitcode);
CloseHandle(pi.hProcess);
if (bRestart)
{
// 0xff - terminated by WerFault
// (int)exitcode < 0 - exception in process
bRestart = exitcode == 0xff || ((int)exitcode < 0);
}
}
} while (bRestart);
}
}
ExitProcess(0);
}
else
{
// main case
wcscpy(CommandLine, CommandLine + 1);
if (MessageBoxW(0, L"make crash ?", CommandLine, MB_YESNO) == IDYES)
{
__debugbreak();// simulate crash
}
ExitProcess(0);
}
}

Is there a way to synchronize this without locks? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
Say I have 3 functions that can be called by an upper layer:
Start - Will only be called if we haven't been started yet, or Stop was previously called
Stop - Will only be called after a successful call to Start
Process - Can be called at any time (simultaneously on different threads); if started, will call into lower layer
In Stop, it must wait for all Process calls to finish calling into the lower layer, and prevent any further calls. With a locking mechanism, I can come up with the following pseudo code:
Start() {
ResetEvent(&StopCompleteEvent);
IsStarted = true;
RefCount = 0;
}
Stop() {
AcquireLock();
IsStarted = false;
WaitForCompletionEvent = (RefCount != 0);
ReleaseLock();
if (WaitForCompletionEvent)
WaitForEvent(&StopCompleteEvent);
ASSERT(RefCount == 0);
}
Process() {
AcquireLock();
AddedRef = IsStarted;
if (AddedRef)
RefCount++;
ReleaseLock();
if (!AddedRef) return;
ProcessLowerLayer();
AcquireLock();
FireCompletionEvent = (--RefCount == 0);
ReleaseLock();
if (FilreCompletionEvent)
SetEvent(&StopCompleteEvent);
}
Is there a way to achieve the same behavior without a locking mechanism? Perhaps with some fancy usage of InterlockedCompareExchange and InterlockedIncremenet/InterlockedDecrement?
The reason I ask is that this is in the data path of a network driver and I would really prefer not to have any locks.
I believe it is possible to avoid the use of explicit locks and any unnecessary blocking or kernel calls.
Note that this is pseudo-code only, for illustrative purposes; it hasn't seen a compiler. And while I believe the threading logic is sound, please verify its correctness for yourself, or get an expert to validate it; lock-free programming is hard.
#define STOPPING 0x20000000;
#define STOPPED 0x40000000;
volatile LONG s = STOPPED;
// state and count
// bit 30 set -> stopped
// bit 29 set -> stopping
// bits 0 through 28 -> thread count
Start()
{
KeClearEvent(&StopCompleteEvent);
LONG n = InterlockedExchange(&s, 0); // sets s to 0
if ((n & STOPPED) == 0)
bluescreen("Invalid call to Start()");
}
Stop()
{
LONG n = InterlockedCompareExchange(&s, STOPPED, 0);
if (n == 0)
{
// No calls to Process() were running so we could jump directly to stopped.
// Mission accomplished!
return;
}
LONG n = InterlockedOr(&s, STOPPING);
if ((n & STOPPED) != 0)
bluescreen("Stop called when already stopped");
if ((n & STOPPING) != 0)
bluescreen("Stop called when already stopping");
n = InterlockedCompareExchange(&s, STOPPED, STOPPING);
if (n == STOPPING)
{
// The last call to Process() exited before we set the STOPPING flag.
// Mission accomplished!
return;
}
// Now that STOPPING mode is set, and we know at least one call to Process
// is running, all we need do is wait for the event to be signaled.
KeWaitForSingleObject(...);
// The event is only ever signaled after a thread has successfully
// changed the state to STOPPED. Mission accomplished!
return;
}
Process()
{
LONG n = InterlockedCompareExchange(&s, STOPPED, STOPPING);
if (n == STOPPING)
{
// We've just stopped; let the call to Stop() complete.
KeSetEvent(&StopCompleteEvent);
return;
}
if ((n & STOPPED) != 0 || (n & STOPPING) != 0)
{
// Checking here avoids changing the state unnecessarily when
// we already know we can't enter the lower layer.
// It also ensures that the transition from STOPPING to STOPPED can't
// be delayed even if there are lots of threads making new calls to Process().
return;
}
n = InterlockedIncrement(&s);
if ((n & STOPPED) != 0)
{
// Turns out we've just stopped, so the call to Process() must be aborted.
// Explicitly set the state back to STOPPED, rather than decrementing it,
// in case Start() has been called. At least one thread will succeed.
InterlockedCompareExchange(&s, STOPPED, n);
return;
}
if ((n & STOPPING) == 0)
{
ProcessLowerLayer();
}
n = InterlockedDecrement(&s);
if ((n & STOPPED) != 0 || n == (STOPPED - 1))
bluescreen("Stopped during call to Process, shouldn't be possible!");
if (n != STOPPING)
return;
// Stop() has been called, and it looks like we're the last
// running call to Process() in which case we need to change the
// status to STOPPED and signal the call to Stop() to exit.
// However, another thread might have beaten us to it, so we must
// check again. The event MUST only be set once per call to Stop().
n = InterlockedCompareExchange(&s, STOPPED, STOPPING);
if (n == STOPPING)
{
// We've just stopped; let the call to Stop() complete.
KeSetEvent(&StopCompleteEvent);
}
return;
}

Run two functions at the same time [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 years ago.
Improve this question
I have two functions. How would i run two functions at the same time? I Know should use threading.
I need a example for Multi Threading . I am using Visual Studio 2010
You can use _beginthread
void CalculatePrimes(void*)
{
// Do something
}
void TransmitFile(void*)
{
// Do domething
}
int main()
{
uintptr_ x = _beginthread(CalculatePrices,0,NULL);
uintptr_ y = _beginthread(TransmitFile,0,NULL);
return 0;
}
If you've got access to C++11 you can use std::thread :
void CalculatePrimes()
{
// Do something
}
void TransmitFile()
{
// Do domething
}
int main()
{
std::thread x(CalculatePrices);
std::thread y(TransmitFile);
// Both function are now running an different thread
// We need to wait for them to finish
x.join();
y.join();
return 0;
}
And, if you want to get down to the metal you can use the CreateThread api :
DWORD WINAPI CalculatePrimes(void *)
{
// Do something
return 0;
}
DWORD WINAPI TransmitFile(void *)
{
// Do something
return 0;
}
int main()
{
HANDLE x=::CreateThread(NULL,0,CalculatePrimes,NULL,0,NULL);
HANDLE y=::CreateThread(NULL,0,CalculatePrimes,NULL,0,NULL);
// Wait for them to finish
::WaitForSingleObject(x,INFINITE);
::WaitForSingleObject(y,INFINITE);
return 0;
}
The MSDN reference for < thread > only goes back to VS2012,not VS2010. You could update to VS2012 (you also need to be running Win 7 or Win 8) Here is a link to a zip of a windows console program written in C that copies a file using two threads, creating a thread to do the writes. It uses windows mutexes and semaphores to implement an inter-thread single linked list messaging interface.
mtcopy.zip
If you are using MFC, you could use AfxBeginThread to create a CWinThread:
UINT SomeFunction(LPVOID pParam)
{
CSomeObject * pObject = (CSomeObject*)pParam;
// do stuff
return 0; // thread completed successfully
}
int main()
{
CSomeObject pObject = new CSomeObject;
AfxBeginThread(SomeFunction, pObject);
...
return 0;
}
For more information, see MSDN for AfxBeginThread.

How to insert a command line to GUI applications [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I need to make a QT GUI application that will be able to run the command line batchs and commands. For example, ping, tcpdump, etc. ...
I would imagine it like this:
The standard graphical window with the QTableView, some checkboxes, etc. ... with a component instance QPlainTextEdit. This component (QPlainTextEdit) will act as a command line, that will allow to enter commands and capture their output.
Is such a thing possible? How should this be done?
You can use QProcess for your purpose..
QProcess cmd;
cmd.start("cmd");
More details here..
http://www.qtcentre.org/threads/12757-QProcess-cmd
The main idea is to use QProcess for running commands. See the code below for demonstration.
Sync approach
QProcess process;
// If "command" is not in your path,
// use the corresponding relative or absolute path
process.start("command", QStringList()
<< QString("-arg1")
<< QString("arg2")
<< QString("-arg3")
<< QString("arg4"));
// Wait for it to start
if(!process.waitForStarted())
return 0;
bool retval = false;
QByteArray buffer;
while ((retval = process.waitForFinished()));
buffer.append(process.readAll());
if (!retval) {
yourPlainTextEdit.appendPlainText(process.errorString());
} else {
yourPlainTextEdit.appendPlainText(buffer);
}
Async approach
MyClass::MyClass(QQProcess *process, QObject *parent)
: QObject(parent)
, m_process(process)
{
connect(m_process, SIGNAL(readyRead()), SLOT(handleReadyRead()));
connect(m_process, SIGNAL(error(QProcess::ProcessError)), SLOT(handleError(QProcess::ProcessError)));
connect(&m_timer, SIGNAL(timeout()), SLOT(handleTimeout()));
m_timer.start(5000);
}
MyClass::~MyClass()
{
}
void MyClass::handleReadyRead()
{
m_readData.append(m_process->readAll());
if (!m_timer.isActive())
m_timer.start(5000);
}
void MyClass::handleTimeout()
{
if (m_readData.isEmpty()) {
yourPlainTextEdit.appendPlainText("No data was currently available for reading from gnuplot");
} else {
yourPlainTextEdit.appendPlainText("Process successfully run");
}
}
void GnuPlotReader::handleError(QProcess::ProcessError processError)
{
if (processError == QProcess::ReadError) {
appendPlainTextEdit.appendPlainText("An I/O error occurred while reading the data, error: %1").arg(m_process->errorString()));
yourPlainTextEdit.appendPlainText(m_readData);
}
}
Disclaimer: This is fully untested code, so it may have compiler and run time issues, but this should give a good grasp of it without further ado.

How to start a executable within a C++ program and get its process id (in linux)? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 9 years ago.
Improve this question
i tried system(), but somehow when the secondary program runs, my main program(primary program which executes the secondary) hangs
and second issue is how do i obtain the process id of the secondary program in my main program?
In the parent process you want to fork.
Fork creates an entirely new process and returns either the child process's pid to the calling process, and 0 to the new child process.
In the child process you can then use something like execl to execute your desired secondary program.
In the parent process you can use waitpid to wait for the child to complete.
Here is a simple illustrative example:
#include <iostream>
#include <sys/wait.h>
#include <unistd.h>
#include <cstdio>
#include <cstdlib>
int main()
{
std::string cmd = "/bin/ls"; // secondary program you want to run
pid_t pid = fork(); // create child process
int status;
switch (pid)
{
case -1: // error
perror("fork");
exit(1);
case 0: // child process
execl(cmd.c_str(), 0, 0); // run the command
perror("execl"); // execl doesn't return unless there is a problem
exit(1);
default: // parent process, pid now contains the child pid
while (-1 == waitpid(pid, &status, 0)); // wait for child to complete
if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
{
// handle error
std::cerr << "process " << cmd << " (pid=" << pid << ") failed" << std::endl;
}
break;
}
return 0;
}
Use fork to create a new process, then exec to run a program in the new process. There are many such examples.