Asynchronous function call, with a method to check progress - c++

I need help to implement an asynchonous funtion call in C++. I am new to multithreading in C++.
There sould be two funtions: one to get the work started in another thread and one to check progress and if work has been finished.
I tried it with some code from different answers on this site, but it doesn't work.
int __stdcall Test::asyncStartWork()
{
asyncReady = false;
std::thread workThread = std::thread(&Test::doWork, this);
return 0;
}
int __stdcall Test::asyncGetProgress()
{
if (asyncReady = true)
{
workThread.join();
return 100;
}
else
{
return asyncProgress;
}
}
int __stdcall Test::doWork()
{
//do work and write progress to asyncProgress
//at the end
asyncReady = true
}
When calling asyncStartWork I get the following error:

In method Test::asyncStartWork(), you are defining a local variable workThread which is hiding your class member.
So in asyncGetProgress(), when calling workThread.join(), you're calling it for a thread object which does not represent a thread (see here).
This results in a std::system_error being thrown with error condition no_such_process. If your program is not catching exceptions, this would result in the process aborting.
Try removing the std::thread part in asyncStartWork(), e.g.
int __stdcall Test::asyncStartWork()
{
asyncReady = false;
workThread = std::thread(&Test::doWork, this);
return 0;
}
Also, the __stdcall's seem unnecessary.

Related

Access variable in main thread from second thread

I have a function (messageArrived) that call's a function (setAnimation) inside a new thread. How can i access a boolean that is defined inside the messageArrived function and access it in the second thread?
If there is a new message i want to terminate the second thread (setAnimation). I fugured that whit a boolean is the only way to "terminate" a thread.
#include <thread>
bool start = false;
void setAnimation(std::string msg){
start = true;
while(start){
//do something
}
return;
}
int messageArrived(std::string message){
start = false;
std::thread t1(setAnimation, message);
t1.detach();
return 1;
}
Above code is just an example to clarify my question.
When creating your thread, you can pass a variable by reference using std::ref However, you would still need to have your variable outside the function, else it will get out of scope.
std::thread t1(setAnimation, message, std::ref(myVariable));

How to return value from nested task in c++/cx?

I have a bunch of threaded tasks like this after each other:
create_task(somewinrtasyncfunction()).then([this(variable_that_the_last_task_returned)
{
//task here
return info;
}).then([this](info)
{
//another task here
return status});
Now I want to use status outside the tasks, in the function that called it. How would I access it?
You return the task (or value) created by create_task(...).then(...).then(...).
If you need to get the result synchronously, you can try calling .get() on the task but that will not work on the main UI thread(s) of your application, and is not something you should do. The code might work on a background thread today, but you might end up calling the function on the UI thread in the future -- perhaps by some very round-about fashion -- and then your app will crash. The only way to fix the app will be to re-engineer your code to be asynchronous... like it should have been in the first place.
Also, note that trying to do your own work-arounds to get the value synchronously (like calling WaitForSingleObjectEx() on an object signaled in the task) can deadlock the UI thread for many WinRT Async methods. Don't do it!
You should continue the asynchronous chain to act on the value. Here is a simple example; call test() from your main UI thread.
concurrency::task<int> get_double_async(int value)
{
return concurrency::create_task(
[value]()
{
return value * 2;
});
}
// DON'T DO THIS - IT IS A BUG FARM WAITING TO HAPPEN!
int try_calling_get()
{
auto value = 2;
value = get_double_async(value).get(); // TODO: Don't do this!
value = get_double_async(value).get(); // TODO: Don't do this!
return value;
}
concurrency::task<int> do_it_properly()
{
auto value = 2;
return get_double_async(value).then([](int value)
{
return get_double_async(value).then([](int value)
{
return value;
});
});
}
void test()
{
wchar_t buff[255];
swprintf_s(buff, L"test() being called on thread %d.\r\n", GetCurrentThreadId());
OutputDebugString(buff);
// this will fail at runtime if called from UI thread
try
{
auto x = try_calling_get();
}
catch (const concurrency::invalid_operation& op)
{
// "Illegal to wait on a task in a Windows Runtime STA"
swprintf_s(buff, L"try_calling_get() threw '%hs'; thread is %d.\r\n",
op.what(), GetCurrentThreadId());
OutputDebugString(buff);
}
// this will "work", but only because it is forced into a threadpool thread
concurrency::create_task([]
{
auto x = try_calling_get(); // TODO: Don't do this!
wchar_t buff[255];
swprintf_s(buff, L"try_calling_get() returned %d; thread is %d.\r\n",
x, GetCurrentThreadId());
OutputDebugString(buff);
});
// this is the preferred way to do it
do_it_properly().then([](int x)
{
wchar_t buff[255];
swprintf_s(buff, L"do_it_properly() returned %d; thread is %d.\r\n",
x, GetCurrentThreadId());
OutputDebugString(buff);
});
}
Note that this example uses value-based continuations .then([](int value){...}) rather than task-based continuations .then([](task<int> value){...}); you would use task-based continuations if you wanted control over things like exceptions.
Here's a sample run (the thread IDs will be different every time, and sometimes the last two will be the same)
test() being called on thread 3576.
First-chance exception at 0x77134598 in UniversalNativeApp.Windows.exe: Microsoft C++ exception: Concurrency::invalid_operation at memory location 0x038CEC94.
try_calling_get() threw 'Illegal to wait on a task in a Windows Runtime STA'; thread is 3576.
try_calling_get() returned 8; thread is 5972.
do_it_properly() returned 8; thread is 9976.

c++ pthread not working

I have a classA which creates a thread and I want the thread running until a variable is set to false.
I create the thread like:
ClassA::ClassA():
m_bContinue(true),
{
pthread_mutex_init(&m_mutex, NULL);
pthread_create(&m_thWorkThread, NULL, &ClassA::ThreadProc, this);
}
I want thread running as long as pClassA->Continue() returns true.
void* ClassA::ThreadProc(void *p) //ThreadProc defined as static member function
{
ClassA *pClassA = reinterpret_cast<ClassA*>(p);
if(pClassA != NULL)
{
while(pClassA->Continue())
{
printf("in the while \n ");
}
}
else
printf("pClassA null \n");
}
Continue is returning m_bcontinue which set to true in the constructor.
bool ClassA::Continue()
{
return bContinue;
}
When I run it, it only enters while loop once and prints "in the while" and program stops. When I do strace, I saw the message +++ killed by SIGSEGV +++.
And when I change the while loop like:
while(1){}
it is working properly. What am I missing?
You cannot launch member functions using pthread_create. Instead, use normal function, pass this to it and call the needed function:
void *ThreadProc (void *p)
{
reinterpret_cast<ClassA*>(p)->ThreadProc (p);
return 0;
}
...
pthread_create(&m_thWorkThread, NULL, &ThreadProc, this);
Or, instead you can use c++11 and its std::thread that allows launching class member functions.
Could the object of type A have a shorter lifetime than the thread ? It seems object A dies too soon. Using while(1), you are no longer referencing A.
Quick question. Where is pthread_join here. I hope you havent missed it. Just curious.

passing one function to different threads

I have to create an application where I'll have to make multiple threads. SoI thought to try making one function and passing it to different threads. Initially I've created two threads and have declared one function to be passed to both of them. All I am trying to do is to pass different integers to those threads and display it in the thread function,here is my code:
DWORD WINAPI Name(LPVOID lpParam)
{
int *Ptr=(int*)lpParam;
for(int j=0;j<2;j++)
{
cout<<"Thread"<<endl;
cout<<*Ptr<<endl;
}
return 0;
}
int main()
{
int a=10,b=15,c=25;
HANDLE thread1,thread2;
DWORD threadID,threadID2;
thread2= CreateThread(NULL,0,Name,LPVOID(a),0,&threadID2);
thread1= CreateThread(NULL,0,Name,LPVOID(b),0,&threadID);
for(int i=0;i<5;i++)
{
cout<<"Main Thread"<<endl;
}
if(thread1==NULL)
{
cout<<"Couldn't Create Thread:("<<endl;
exit(0);
}
if(thread2==NULL)
{
cout<<"Couldn't Create Thread:("<<endl;
exit(0);
}
return 0;
}
but this code is not running properly,i.e compliles fine,starts fine but afterwards gives a debugging error.
Could someone let let me know of my mistake and how I could correct it coz being able to utilize one function for multiple threads will be really helpful for me.
Wait for your child threads to return. Do this:
int main()
{
int a=10,b=15,c=25;
HANDLE thread[2];
DWORD threadID,threadID2;
thread[1]= CreateThread(NULL,0,Name,LPVOID(a),0,&threadID2);
thread[0]= CreateThread(NULL,0,Name,LPVOID(b),0,&threadID);
for(int i=0;i<5;i++)
{
cout<<"Main Thread"<<endl;
}
if(thread[0]==NULL)
{
cout<<"Couldn't Create Thread:("<<endl;
exit(0);
}
if(thread[1]==NULL)
{
cout<<"Couldn't Create Thread:("<<endl;
CloseHandle(thread[0]);
exit(0);
}
WaitForMultipleObjects(2, thread, TRUE, INFINITE);
CloseHandle(thread[0]);
CloseHandle(thread[1]);
return 0;
}
The handle of a thread is signaled when the thread is terminated (refer CreateThread).
You are passing the address of a local variable in the function into your thread. By the time the thread gets around to running your function has probably exited main already. So the thread will try to access a variable that no longer exists on the stack so will be reading some random value which when you try to dereference it as a pointer will likely crash.
You main needs to wait. For a simple test just put in a Sleep(10000) or something before it exits. Obviously that's no use for a real program.
To summarize the comments: There are two ways you can pass data. Either directly inside the void pointer, because "void pointer" is an integral type and thus can represent integers (but it doesn't necessarily have the same width as int), or indirectly by passing an actual address of the thing you care about.
Method 1 (pass the value):
DWORD WINAPI Name(LPVOID lpParam)
{
intptr_t n = reinterpret_cast<intptr_t>(lpParam);
// ...
}
int main()
{
intptr_t a = 10;
thread1 = CreateThread(NULL, 0, Name, reinterpret_cast<void *>(a), 0, &threadID);
// ... ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
}
For this method, we use the integral type intptr_t, which has the same width as void *. We use reinterpret-casts to store and retrieve arbitrary integral values.
Method 2 (pass a pointer):
DWORD WINAPI Name(LPVOID lpParam)
{
T * p = static_cast<T *>(lpParam);
// ... use *p ...
}
int main()
{
T thing_I_care_about;
thread1 = CreateThread(NULL, 0, Name, &thing_I_care_about, 0, &threadID);
// ... ^^^^^^^^^^^^^^^^^^^
}
This is the more general method, but requires that thing_I_care_about remain alive, and it becomes a brittle shared state, so lifetime management and synchronisation become issues. Note that any object pointer is implicitly convertible to void *, so there's no need for the cast at the call site.
Finally, as others have commented, don't forget to join or detach your threads.

How to get pointer from another thread?

Let's have the following class definition:
CThread::CThread ()
{
this->hThread = NULL;
this->hThreadId = 0;
this->hMainThread = ::GetCurrentThread ();
this->hMainThreadId = ::GetCurrentThreadId ();
this->Timeout = 2000; //milliseconds
}
CThread::~CThread ()
{
//waiting for the thread to terminate
if (this->hThread) {
if (::WaitForSingleObject (this->hThread, this->Timeout) == WAIT_TIMEOUT)
::TerminateThread (this->hThread, 1);
::CloseHandle (this->hThread);
}
}
//*********************************************************
//working method
//*********************************************************
unsigned long CThread::Process (void* parameter)
{
//a mechanism for terminating thread should be implemented
//not allowing the method to be run from the main thread
if (::GetCurrentThreadId () == this->hMainThreadId)
return 0;
else {
m_pMyPointer = new MyClass(...);
// my class successfully works here in another thread
return 0;
}
}
//*********************************************************
//creates the thread
//*********************************************************
bool CThread::CreateThread ()
{
if (!this->IsCreated ()) {
param* this_param = new param;
this_param->pThread = this;
this->hThread = ::CreateThread (NULL, 0, (unsigned long (__stdcall *)(void *))this->runProcess, (void *)(this_param), 0, &this->hThreadId);
return this->hThread ? true : false;
}
return false;
}
//*********************************************************
//creates the thread
//*********************************************************
int CThread::runProcess (void* Param)
{
CThread* thread;
thread = (CThread*)((param*)Param)->pThread;
delete ((param*)Param);
return thread->Process (0);
}
MyClass* CThread::getMyPointer() {
return m_pMyPointer;
}
In the main program, we have the following:
void main(void) {
CThread thread;
thread.CreateThread();
MyClass* myPointer = thread.getMyPointer();
myPointer->someMethod(); // CRASH, BOOM, BANG!!!!
}
At the moment the myPointer is used ( in the main thread ) it crashes. I don't know how to get the pointer, which points to memory, allocated in another thread. Is this actually possible?
The memory space for your application is accessible to all threads. By default any variable is visible to any thread regardless of context (the only exception would be variables declared __delcspec(thread) )
You are getting a crash due to a race condition. The thread you just created hasn't started running yet at the point where you call getMyPointer. You need to add some kind of synchronization between the newly created thread and the originating thread. In other words, the originating thread has to wait until the new thread signals it that it has created the object.
I'm trying to get my head around what you are trying to do. It looks overly complicated for something like a thread-class. Would you mind post the class-definition as well?
Start by removing the C-style cast of the process-argument to CreateThread():
this->hThread = ::CreateThread (NULL, 0,&runProcess, (void *)(this_param), 0, &this->hThreadId);
If this doesn't compile you're doing something wrong! Never ever cast a function pointer! If the compiler complains you need to change your function, not try to cast away the errors! Really! You'll only make it worse for yourself! If you do it again they* will come to your home and do ... Let's see how you like that! Seriously, don't do it again.
Btw, in Process() I think it would be more appropriate to do something like:
assert(::GetCurrentThreadId() == hThreadId);
But if you declare it private it should only be accessible by your CThread-class anyway and therefor it shouldn't be a problem. Asserts are good though!
*It's not clear who they are but it's clear whatever they do it won't be pleasant!
As Rob Walker pointed out - I really missed the race condition. Also the crash is not when getting the pointer, but when using it.
A simple wait did the job:
MyClass* myPointer = thread.getMyPointer();
while (myPointer == 0)
{
::Sleep(1000);
}
myPointer->someMethod(); // Working :)