Defining function inside function call - c++

I had an idea to save time involving creating a temporary function to use as an argument to a function that needs it. The reason I'm after this behaviour is to do things in a new thread in an easy manner (using Win32 API) without having to define all kinds of functions I'll use.
Here's an example:
void msg (const string & message) {
MessageBox (0, message.c_str(), "Message", 0);
}
This will produce a message box, but your program is halted until it closes. The solution is to create a thread for the message box that runs concurrently with the main thread.
void msg (const string & message) {
CreateThread (0, 0,
(LPTHREAD_START_ROUTINE)({MessageBox (0, message.c_str(), "Message", 0);}),
0, 0, 0);
}
In this case, LPTHREAD_START_ROUTINE is defined as
typedef DWORD (*LPTHREAD_START_ROUTINE)(LPVOID param);
Since I have multiple functions wanting another thread for a purpose like that, putting the function in the call to CreateThread seems to be working well.
But say I wanted to use that LPVOID param. I'd like to know how standard this method is, and where I can find out how to use it for more advanced techniques. Also, I know using it in a function that will store it for later use (eg. a message loop function where you can add messages to handle and a corresponding function to call) is a bad idea as the function is temporary and would not be able to be called when needed. Is there really any use beyond things like threads where it's annoying to make one line functions elsewhere in order to use it?

It's called a "lambda". They are very useful for many purposes beyond this and are in the C++11 Standard. You can find them in the latest GCC and MSVC. However, MSVC's current implementation does not permit conversion to a function pointer, as the Standard did not specify such a conversion at that time. VC11 will implement this conversion. This code is Standard-conforming C++11:
void msg (const string & message) {
CreateThread (0, 0,
[](LPVOID* param) { MessageBox (0, message.c_str(), "Message", 0); },
0, 0, 0);
}

There was another way in times lambdas were not the standard - you could define function-local class and define the inner function within that class. Something like:
void msg(const string &message)
{
struct message_box
{
static DWORD WINAPI display(LPVOID param)
{
/// do the action
return 0;
}
};
::CreateThread(0, 0,
&message_box::display,
0, 0, 0);
}
Now lets consider your question. You wanted to pass the message text in STL's std::string. Since it occupies dynamic memory which can be freed by your initial thread, the new thread, running in parallel, must have guarantee, that the message text will still be available to it. This can be done by copying (which would work with lambda's by-value capture - [=] introducer) or sharing a reference (via reference counting, let'd say). Lets consider copying:
void msg(const string &message)
{
struct message_box
{
static DWORD WINAPI display(void *param)
{
MessageBox(0, ((string *)param)->c_str(), "Message", 0);
delete (string *)param;
return 0;
}
};
string *clone = new string(message);
::CreateThread(0, 0,
&message_box::display,
clone, 0, 0);
}
Please, note, that the copy is allocated in the initial thread and destroyed in the new one. This requires multithreading support from your CRT.
In the case new thread fails to start, you'll end up with memory being orphaned. Lets fix this:
void msg(const string &message)
{
struct message_box
{
static DWORD WINAPI display(void *param)
{
auto_ptr<string> message((string *)param);
MessageBox(0, message->c_str(), "Message", 0);
return 0;
}
};
auto_ptr<string> clone(new string(message));
if (::CreateThread(0, 0, &message_box::display, clone.get(), 0, 0))
clone.release(); // release only if the new thread starts successfully.
}
Since the memory is being managed by the CRT, the CRT have to be initialized in the new thread, which is not done by CreateThread API. You have to use CRT beginthread/beginthreadex instead:
void msg(const string &message)
{
struct message_box
{
static unsigned int WINAPI display(void *param)
{
auto_ptr<string> message((string *)param);
MessageBox(0, message->c_str(), "Message", 0);
return 0;
}
};
auto_ptr<string> clone(new string(message));
if (_beginthreadex(0, 0, &message_box::display, clone.get(), 0, 0))
clone.release(); // release only if the new thread starts successfully.
}
This solution leaves aside the problem of the thread itself being leaked as a resource. But, I believe you may find another posts for this on stackoverflow.com :)
thanks )

Related

How to handle a PostMessageThread message in std::thread?

Somewhere in my main thread I am calling PostThreadMessage(). But I don't know how to handle it in the std::thread I have sent it to.
I am trying to handle it in std::thread like this:
while(true) {
if(GetMessage(&msg, NULL, 0, 0)) {
// Doing appropriate stuff after receiving the message.
}
}
And I am sending the message from the main thread like this:
PostThreadMessage(thread.native_handle(), WM_CUSTOM_MESSAGE, 0, 0);
I don't know if I am supposed to receive the message as I did in my thread.
All I want to know is, how to check whether the "worker thread" is receiving the message I am sending it.
What std::thread::native_handle() returns is implementation-defined (per [thread.req.native] in the C++ standard). There is no guarantee that it even returns a thread ID that PostThreadMessage() wants.
For instance, MSVC's implementation of std::thread uses CreateThread() internally, where native_handle() returns a Win32 HANDLE. You would have to use GetThreadId() to get the thread ID from that handle.
Other implementations of std::thread might not use CreateThread() at all. For instance, they could use the pthreads library instead, where native_handle() would return a pthread_t handle, which is not compatible with Win32 APIs.
A safer way to approach this issue is to not use native_handle() at all. Call GetCurrentThreadId() inside of your thread function itself, saving the result to a variable that you can then use with PostThreadMessage() when needed, for example:
struct threadInfo
{
DWORD id;
std::condition_variable hasId;
};
void threadFunc(threadInfo &info)
{
info.id = GetCurrentThreadId();
info.hasId.notify_one();
MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) {
// Doing appropriate stuff after receiving the message.
}
}
...
threadInfo info;
std::thread t(threadFunc, std::ref(info));
info.hasId.wait();
...
PostThreadMessage(info.id, WM_CUSTOM_MESSAGE, 0, 0);

How can i implement CreateThread - LPTHREAD_START_ROUTINE type ThreadProc callback function inside a C++ Class

Happy new year!
This is my baby steps in C++ world.
I used an example from learn.microsoft.com to create an example Win32 Console project which uses the WaitForMultipleObjects function to persist until all worker threads have terminated. All worked great!
Things get complicated (argument of type DWORD (Thread::*)(LPVOID lpParam) is incompatible with parameter of type "LPTHREAD_START_ROUTINE")
when i start to try to port the functionality of the concept inside a class which is similar like this:
class Threads
{
private:
HANDLE comThreads[1];
DWORD WINAPI closeThreadProc(LPVOID lpParam)
{
// lpParam not used in this example.
UNREFERENCED_PARAMETER(lpParam);
printf("Thread %d exiting\n", GetCurrentThreadId());
return 1;
}
BOOL CreateThreads(void)
{
DWORD dwThreadID;
comThreads[0] = CreateThread(
NULL, // default security
0, // default stack size
closeThreadProc, // Close thread function
NULL, // no thread parameters
0, // default startup flags
&dwThreadID);
}
public:
void Init()
{
CreateThreads();
}
}
I will try to use this class to create a Dynamic-link library(DLL).
While i am searching the answer to my own question.
I would like to ask you:
Is this even possible?
If it is possible. How can i achieve this, without loosing the underlying concept?
Thank you!
Edit:
Sorry for forgetting to tell if is it possible to make this, without making DWORD WINAPI closeThreadProc(LPVOID lpParam) static!
I did try to make it static before i posted the Question and things became even more wild (I barely forced to make everything in the class static).
I think this is the C++'s way to punish a rookie.
The LPVOID argument is there for a reason. The trick is to make the callback a static member but pass this as the extra parameter. You can then cast the LPVOID argument back to your object and call the method you want to. Some code will make it clearer
static DWORD WINAPI closeThreadProcCallback(LPVOID lpParam)
{
return static_cast<Threads*>(lpParam)->closeThreadProc();
}
BOOL CreateThreads(void)
{
DWORD dwThreadID;
comThreads[0] = CreateThread(
NULL, // default security
0, // default stack size
closeThreadProcCallback, // Close thread callback function
this, // this object is the thread parameter
0, // default startup flags
&dwThreadID);
}
EDIT added WINAPI as suggested by Tomer W.
a threadStartfunction cant be _thiscall, and have to be _stdcall,
therefore i'd declare a static private method to pass your call to your object, i use the lpParameter to pass the object to the static function.
class Threads
{
private:
HANDLE comThreads[1];
static DWORD WINAPI staticThreadProc(LPVOID lpParam)
{
Threads& callingThread = *reinterpret_cast<Threads*>(lpParam);
return callingThread.closeThreadProc();
}
DWORD closeThreadProc()
{
printf("Thread %d exiting\n", GetCurrentThreadId());
return 1;
}
BOOL CreateThreads(void)
{
DWORD dwThreadID;
comThreads[0] = CreateThread(
NULL, // default security
0, // default stack size
staticThreadProc, // Close thread function
this, // no thread parameters
0, // default startup flags
&dwThreadID);
}
public:
void Init()
{
CreateThreads();
}
}

How to deal with multiple parameters of different types in C++98?

In order to implement a thread class(In C++98 and Windows.h). I have something like this:
Thread::Thread(_beginthreadex_proc_type fn)
{
m_raw = fn;
m_args = 0;
m_handle = 0;
m_id = 0;
}
The code above works fine it takes a function that not receive parameters, and with the next code it function is called by a new thread:
void Thread::Join()
{
m_handle = (HANDLE)_beginthreadex(0, 0, m_raw, (m_args ? m_args : 0), 0, 0);
if (m_handle) WaitForSingleObject(m_handle, INFINITE);
}
This code also works fine with functions that don't take any parameter.
Now my question is about how can i in C++98 receive variadic parameters in my constructor and save them.
And NO i can't use modern c++ if that was the case I din't need help. So plz don't give me solutions implemented with c++11 or higher.
Update
Now I'm trying a Java style solution in that every Thread is a IRunnable that have a pure virtual function named Run. And thread is almost the that this implementetation with the diff that is an abstract class. In this way can i avoid parameters because I don't pass the function instead of that I write another class that inherits from Thread and implements Run.
The code look like:
The interface
struct IRunnable
{
virtual void Run() = 0;
};
Thread class
class Thread : public IRunnable
{
HANDLE m_handle;
DWORD m_id;
typedef unsigned (__stdcall *Function)(void*);
_beginthreadex_proc_type m_raw;
void* m_args;
public:
Thread();
~Thread();
Thread(_beginthreadex_proc_type, void*);
Thread(_beginthreadex_proc_type);
unsigned GetId();
virtual void Run() = 0;
void Join();
unsigned int __stdcall call(void*);
};
Call only is a wrapper to call Run function member
unsigned int __stdcall Thread::call(void* data)
{
Run();
return 0;
}
My problem is here:
void Thread::Join()
{
m_handle = (HANDLE)_beginthreadex(0, 0, &this->call, 0, 0, 0);
if (m_handle) WaitForSingleObject(m_handle, INFINITE);
}
When i compiling in vs2019 the code above produce the next error:
error C2276: '&': illegal operation on bound member function expression
error C2660: '_beginthreadex': function does not take 5 arguments
For your edited question, the reason you're getting a compile error is because you're trying to send the address to a member function of your Thread object. You can't take pointers to member functions and use them without also keeping the object pointer around. Instead, you should make a global function that takes a Thread* as its argument, send a pointer to that function, and let it call your runnable.
unsigned thread_entry(void* thread_ptr)
{
Thread* thread = (Thread*) thread_ptr;
return thread->call();
}
void Thread::Join()
{
m_handle = (HANDLE)_beginthreadex(0, 0, thread_entry, this, 0, 0);
if (m_handle) WaitForSingleObject(m_handle, INFINITE);
}
P.S. It's usually best to ask new questions instead of editing old ones if the question is significantly different, which yours is.
If you look at pretty much any thread library, they very rarely support sending multiple arguments; you usually send a pointer to something, and if you want many things, you make a struct containing many things and send a pointer to it.
However, if you really want this, you could use the C varargs functions to iterate over all variadic arguments, and allocate a linked list with them, or allocate an array of them, or whatever other data structure you want. Then, send a pointer to that to your thread entry function. Your function would still be taking just one pointer, though.
In C, there is no easy way to construct a va_list, which is how variadic arguments are sent around. You can't just send the va_list you have on your main thread, because that memory won't be alive by the time it reaches your new thread. There is also no good way to expand a va_list to fill function arguments.
Btw, I realize you're using C++, but as far as C++98 goes, its varargs support is basically the same as in C, which is why I'm mentioning C in my answer.

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.

Trouble referencing class in structure using this keyword

Header file:
// Free function to use in thread
unsigned int __stdcall WorkerFunction(void *);
class MyClass {
public:
int temp;
void StartThread();
}
typedef struct {
MyClass * cls;
} DATA;
CPP class:
void MyClass::StartThread() {
temp = 1234;
DATA data = {this};
HANDLE hThread = (HANDLE) _beginthreadex(0, 0, &WorkerFunction, &data, 0, 0);
// Commented out for now while I address the current problem
//CloseHandle(hThread);
}
unsigned int __stdcall WorkerFunction(void * param0) {
MessageBox(NULL, "WorkerFunction()", "Alert", MB_OK);
DATA * data = (DATA *) param0;
MyClass* cls0 = data->cls;
// Crashes when reference to cls0 is attempted.
char buf[5];
snprintf(buf, 5, "%i", cls0 ->temp);
MessageBox(NULL, buf, "Alert", MB_OK);
}
I've got an easy problem here that I can't put my finger on.
I have params for a thread, which pass a struct which contains a class.
I instantiate the struct with this and then pass it when the thread starts
I try to dereference (?) it in the worker function.
At this point, everything compiles OK.
When I add lines to access something in the class, the app crashes.
Where is my mistake?
You're passing a local stack variable that is out-of-scope the moment StartThread() returns. You are therefore referencing stack-space that no longer belongs to you.
void MyClass::StartThread() {
temp = 1234;
DATA data = {this}; // << LOCAL VARIABLE OUT OF SCOPE ON FUNCTION EXIT
HANDLE hThread = (HANDLE) _beginthreadex(0, 0, &WorkerFunction, &data, 0, 0);
// Commented out for now while I address the current problem
//CloseHandle(hThread);
}
Either dynamically allocate the data, or better still, make the data a member of MyClass and pass this as the thread data. In your case you're only passing *this anyway through a struct, so just pass it as the param
void MyClass::StartThread() {
temp = 1234;
HANDLE hThread = (HANDLE) _beginthreadex(0, 0, &WorkerFunction, this, 0, 0);
// Commented out for now while I address the current problem
//CloseHandle(hThread);
}
And in your thread proc:
unsigned int __stdcall WorkerFunction(void * param0) {
MessageBox(NULL, "WorkerFunction()", "Alert", MB_OK);
MyClass* cls0 = static_cast<MyClass*>(param0);
etc...
}
Whatever you pass to your thread procedure, it must have valid lifetime for the duration required. by the thread. Either ensure that by passing ownership of a dynamic allocation to the thread at let it do the delete, or pass a pointer known hold determinate state for the lifetime of its usage in the thread-proc. It appears this fulfills the latter, so you should likely be good to go.