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.
Related
I am using a SDK that provides some functions and one callback to send the results. Code is in C++.
SDK APIs:
typedef void(*onSdkCallBackFn)(int cmdType, const char *jsonResult);
void SetCallback(onSdkIotCallBackFn Fn);
void SetCommand(int commandId);
There is no return value for SetCommand, so need to wait for SDK to send the result through callback.
I need to provide my own API for upper layer, but they expect to get the result by function call and do not intend to receive it through callback.
here is my sample code:
void MyCallback(int cmdType, const char *jsonResult)
{
int result;
if (cmfType == 5)
result = 100;
else
result = 0;
}
int DoCommandNo5()
{
int result = -1; // need to be updated in callback function
etCallback(&MyCallback);
DoCommand(5);
// here I need to wait for result through SDK callback and return it.
// How to handle it?
return result;
}
Can I do this without using threads? What is the best way to handle this task?
I checked these approaches: WaitForSingleObject and std::condition_variable but seems for both need create separate thread.
Any advise and help is appreciated.
Well one way to do it is to e.g. wait on std::condition_variable:
int DoCommandNo5()
{
int result = -1;
bool resultReady = false;
std::mutex m;
std::unique_lock<std::mutex> lk(m);
std::condition_variable cv;
auto getResult = [&](int commandResult) {
resultReady = true;
result = commandResult;
cv.notify_one();
};
setCallback(getResult);
doCommand(5);
cv.wait(lk, [&]{return resultReady;});
return result;
}
You can also call cv.wait_for method so DoCommandNo5 function doesn't block infinitely.
Since the details are vague, I will answer from a very general perspective of how to wrap an event driven based functionality into a standard function.
I expect result to be accessible globally or passed somehow to the callback function. Therefore, in the function expecting the callback to set an actual result, one can just do waiting while loop. e.g.:
int result;
void TheCallback() {
...
result = 255;
...
}
int TheCallbackWrapper() {
...
result = -1; // let's assume -1 means result is not yet set
while (result == -1) {
sleep(1); // an assumption of system call to sleep the execution for 1 ms, just not to eat CPU time too much
}
return result; // if we reach this point, then the callback has set a result ready to be returned
}
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.
Hy,
I'm writing my first Qt program and getting now in troubles with:
QObject::killTimer: timers cannot be stopped from another thread
QObject::startTimer: timers cannot be started from another thread
My program will communicate to a CANOpen bus for that I'm using the Canfestival Stack. The Canfestival will work with callback methods. To detects timeout in communication I setup a timer function (somehow like a watchdog). My timer package consist out of a "tmr" module, a "TimerForFWUpgrade" module and a "SingleTimer" module. The "tmr" module was originally C programmed so the static "TimerForFWUpgrade" methods will interface it. The "tmr" module will be part of a C programed Firmware update package.
The timer will work as follows. Before a message is sent I will call TMR_Set method. An then in my idle program loop with TMR_IsElapsed we check for a timer underflow. If TMR_IsElapsed I will do the errorhandling. As you see the TMR_Set method will be called continuously and restart the QTimer again and again.
The above noted errors are appearing if I start my program. Can you tell me if my concept could work? Why does this errors appear? Do I have to use additional threads (QThread) to the main thread?
Thank you
Matt
Run and Idle loop:
void run
{
// start communicate with callbacks where TMR_Set is set continously
...
while(TMR_IsElapsed(TMR_NBR_CFU) != 1);
// if TMR_IsElapsed check for errorhandling
....
}
Module tmr (interface to C program):
extern "C"
{
void TMR_Set(UINT8 tmrnbr, UINT32 time)
{
TimerForFWUpgrade::set(tmrnbr, time);
}
INT8 TMR_IsElapsed(UINT8 tmrnbr)
{
return TimerForFWUpgrade::isElapsed(tmrnbr);
}
}
Module TimerForFWUpgrade:
SingleTimer* TimerForFWUpgrade::singleTimer[NR_OF_TIMERS];
TimerForFWUpgrade::TimerForFWUpgrade(QObject* parent)
{
for(unsigned char i = 0; i < NR_OF_TIMERS; i++)
{
singleTimer[i] = new SingleTimer(parent);
}
}
//static
void TimerForFWUpgrade::set(unsigned char tmrnbr, unsigned int time)
{
if(tmrnbr < NR_OF_TIMERS)
{
time *= TimerForFWUpgrade::timeBase;
singleTimer[tmrnbr]->set(time);
}
}
//static
char TimerForFWUpgrade::isElapsed(unsigned char tmrnbr)
{
if(true == singleTimer[tmrnbr]->isElapsed())
{
return 1;
}
else
{
return 0;
}
}
Module SingleTimer:
SingleTimer::SingleTimer(QObject* parent) : QObject(parent),
pTime(new QTimer(this)),
myElapsed(true)
{
connect(pTime, SIGNAL(timeout()), this, SLOT(slot_setElapsed()));
pTime->setTimerType(Qt::PreciseTimer);
pTime->setSingleShot(true);
}
void SingleTimer::set(unsigned int time)
{
myElapsed = false;
pTime->start(time);
}
bool SingleTimer::isElapsed()
{
QCoreApplication::processEvents();
return myElapsed;
}
void SingleTimer::slot_setElapsed()
{
myElapsed = true;
}
Use QTimer for this purpose and make use of SIGNALS and SLOT for the purpose of starting and stopping the timer/s from different threads. You can emit the signal from any thread and catch it in the thread which created the timer to act on it.
Since you say you are new to Qt, I suggest you go through some tutorials before proceeding so that you will know what Qt has to offer and don't end up trying to reinvent the wheel. :)
VoidRealms is a good starting point.
You have this problem because the timers in the static array is created in Thread X, but started and stopped in Thread Y. This is not allowed, because Qt rely on thread affinity to timeout timers.
You can either create, start stop in the same thread or use signal and slots to trigger start and stop operations for timers. The signal and slot solution is a bit problematic Because you have n QTimer objects (Hint: how do you start the timer at position i?)
What you can do instead is create and initialize the timer at position tmrnbr in
TimerForFWUpgrade::set(unsigned char tmrnbr, unsigned int time)
{
singleTimer[tmrnbr] = new SingleTimer(0);
singleTimer[tmrnbr]->set(time);
}
which is executed by the same thread.
Futhermore, you don't need a SingleTimer class. You are using Qt5, and you already have all you need at your disposal:
SingleTimer::isElapsed is really QTimer::remainingTime() == 0;
SingleTimer::set is really QTimer::setSingleShot(true); QTimer::start(time);
SingleTimer::slot_setElapsed becomes useless
ThusSingleTimer::SingleTimer becomes useless and you dont need a SingleTimer class anymore
I got the errors away after changing my timer concept. I'dont use anymore my SingleTimer module. Before the QTimer I won't let timeout and maybe because of that I run into problems. Now I have a cyclic QTimer that times out every 100ms in slot function I will then count the events. Below my working code:
TimerForFWUpgrade::TimerForFWUpgrade(QObject* parent) : QObject(parent),
pTime(new QTimer(this))
{
connect(pTime, SIGNAL(timeout()), this, SLOT(slot_handleTimer()));
pTime->setTimerType(Qt::PreciseTimer);
pTime->start(100);
}
void TimerForFWUpgrade::set(unsigned char tmrnbr, unsigned int time)
{
if(tmrnbr < NR_OF_TIMERS)
{
if(timeBase != 0)
{
myTimeout[tmrnbr] = time / timeBase;
}
else
{
myTimeout[tmrnbr] = 0;
}
myTimer[tmrnbr] = 0;
myElapsed[tmrnbr] = false;
myActive[tmrnbr] = true;
}
}
char TimerForFWUpgrade::isElapsed(unsigned char tmrnbr)
{
QCoreApplication::processEvents();
if(tmrnbr < NR_OF_TIMERS)
{
if(true == myElapsed[tmrnbr])
{
return 1;
}
else
{
return 0;
}
}
else
{
return 0; // NOK
}
}
void TimerForFWUpgrade::slot_handleTimer()
{
for(UINT8 i = 0; i < NR_OF_TIMERS; i++)
{
if(myActive[i] == true)
{
myTimer[i]++;
if(myTimeout[i] < myTimer[i])
{
myTimer[i] = 0;
myElapsed[i] = true;
myActive[i] = false;
}
}
}
}
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.
I think I am making a simple mistake, but since I noticed there are many boost experts here, I thought I would ask for help.
I am trying to use boost threads(1_40) on windows xp. The main program loads a dll, starts the thread like so (note this is not in a class, the static does not mean static to a class but private to the file).
static boost::thread network_thread;
static bool quit = false;
HANDLE quitEvent;
//some code omitted for clarity, ask if you think it would help
void network_start()
{
HANDLE *waitHandles = (HANDLE*)malloc(3 * sizeof(HANDLE));
waitHandles[0] = quitEvent;
waitHandles[1] = recvEvent;
waitHandles[2] = pendingEvent;
do {
//read network stuff, or quit event
dwEvents =WaitForMultipleObjects(3, waitHandles, FALSE, timeout);
} while (!quit)
}
DllClass::InitInstance()
{
}
DllClass::ExportedFunction()
{
network_thread = boost::thread(boost::bind<void>(network_start));
}
DllClass::ExitInstance()
{
//signal quit (which works)
quit = true;
SetEvent(QuitEvent);
//the following code is slightly verbose because I'm trying to figure out what's wrong
try {
if (network_thread.joinable() ) {
network_thread.join();
} else {
TRACE("Too late!");
}
} catch (boost::thread_interrupted&) {
TRACE("NET INTERRUPTED");
}
}
The problem is that the main thread is hanging on the join, and the network thread is hanging at the end of _endthreadex. What am I misunderstanding?
You are not supposed to create/end threads in InitInstance/ExitInstance,
see http://support.microsoft.com/default.aspx?scid=kb;EN-US;142243 for more info. Also, see http://msdn.microsoft.com/en-us/library/ms682583%28VS.85%29.aspx about DllMain in general.