Lambdas and threads - c++

I've recently started using lambdas an awful lot within threads, and want to make sure I'm not setting myself up for thread-safety issues/crashes later. My usual way of using them is:
class SomeClass {
int someid;
void NextCommand();
std::function<void(int, int)> StoreNumbers;
SomeClass(id, fn); // constructor sets id and storenumbers fn
}
// Called from multiple threads
static void read_callback(int fd, void* ptr)
{
SomeClass* sc = static_cast<SomeClass*>ptr;
..
sc->StoreNumbers(someint,someotherint); // voila, thread specific storage.
}
static DWORD WINAPI ThreadFn(LPVOID param)
{
std::list<int> ints1;
std::list<int> ints2;
auto storenumbers = [&] (int i, int i2) {
// thread specific lambda.
ints1.push_back(i);
ints2.push_back(i2);
};
SomeClass s(id, storenumbers);
...
// set up something that eventually calls read_callback with s set as the ptr.
}
ThreadFn is used as the thread function for 30-40 threads.
Is this acceptable? I usually have a few of these thread-specific lambdas that operate on a bunch of thread specific data.
Thank you!

There's no problem here. A data access with a lambda is no different to a data access with a named function, through inline code, a traditional functor, one made with bind, or any other way. As long as that lambda is invoked from only one thread at a time, I don't see any evidence of thread-related problems.

Related

Execute lambda with CreateThread

Is there a better way to use CreateThread than creating a free function each time for the sole purpose of casting lpParameter?
Are there any modern alternatives to CreateThread for creating persistent threads?
Edit: Perhaps you should just use std::async(lambda). I imagine that it's just implemented with CreateThread. Maybe the answer to this question is looking up how std::async is implemented (assuming it's a library feature).
DWORD WINAPI MyThreadFunction(
_In_ LPVOID lpParameter
)
{
((MyClass*)lpParameter)->RunLoop();
}
void MyClass::LaunchThread()
{
CreateThread(
NULL, // default security attributes
0, // use default stack size
MyThreadFunction, // thread function name
this, // argument to thread function
0, // use default creation flags
NULL); // returns the thread identifier
}
There are several mechanisms for achieving parallelism (std::async etc. as mentioned above).
But the modern one which is most similar to your original code with CreateThread is std::thread. It can be constructed with a global function, a lambda, or a class method (which seems the best fit for you):
m_thread = std::thread([this](){ RunLoop(); }); // pass a lambda
or
m_thread = std::thread(&MyClass::RunLoop, this); // pass a method
Note that a std::thread starts to run (potentially) when constructed. Also note that, std::async does not guarantee that it will run on a separate thread and even if it does run on a thread, it could be a thread from a pool. The behaviour might not be the same as with your original CreateThread.
Here's a complete example of using std::thread (including cancellation):
#include <thread>
#include <chrono>
#include <atomic>
#include <iostream>
class MyClass
{
public:
MyClass() {}
~MyClass() { EndThread(); }
void LaunchThread()
{
EndThread(); // in case it was already running
m_bThreadShouldExit = false;
// Start the thread with a class method:
m_thread = std::thread(&MyClass::RunLoop, this);
}
void EndThread()
{
// Singal the thread to exit, and wait for it:
m_bThreadShouldExit = true;
if (m_thread.joinable())
{
m_thread.join();
}
}
void RunLoop()
{
std::cout << "RunLoop started" << std::endl;
while (!m_bThreadShouldExit)
{
std::cout << "RunLoop doing something ..." << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}
std::cout << "RunLoop ended" << std::endl;
}
private:
std::thread m_thread;
std::atomic_bool m_bThreadShouldExit{ false };
};
int main()
{
MyClass m;
m.LaunchThread();
std::this_thread::sleep_for(std::chrono::milliseconds(5000));
m.EndThread();
}
Possible output:
RunLoop started
RunLoop doing something ...
RunLoop doing something ...
RunLoop doing something ...
RunLoop doing something ...
RunLoop doing something ...
RunLoop ended
std::async() and std::thread(, <args...>) are most likely internally implemented as you just did, the only exception is that lambdas without captures can be implicitly converted to function pointers, which pretty much can be passed straight away to CreateThread function with nullptr lpParameter.
Lambdas with capture list are pretty much syntactic sugar but internally they translate to sth like this (very simplified):
struct <internal_lambda_name>
{
<capture list...> fields...;
void operator()(<arguments...>){<code...>;}
};
So they pretty much translate to objects of struct type thus they need some way to store all those captures and in order to be executed on other thread with CreateThread function they need some way of ensuring that the capture list data stored in them will be available during their execution.
I looked in to MSVC implementation of std::async and they implemented it using ::Concurrency::create_task which straight forwardly accepts a callable object.
https://learn.microsoft.com/en-us/cpp/parallel/concrt/task-parallelism-concurrency-runtime
I also looked into their implementation of create_task
template<typename _Ty>
__declspec(noinline) // Ask for no inlining so that the _CAPTURE_CALLSTACK gives us the expected result
explicit task(_Ty _Param)
{
task_options _TaskOptions;
details::_ValidateTaskConstructorArgs<_ReturnType,_Ty>(_Param);
_CreateImpl(_TaskOptions.get_cancellation_token()._GetImplValue(), _TaskOptions.get_scheduler());
// Do not move the next line out of this function. It is important that _CAPTURE_CALLSTACK() evaluates to the call site of the task constructor.
_SetTaskCreationCallstack(_CAPTURE_CALLSTACK());
_TaskInitMaybeFunctor(_Param, decltype(details::_IsCallable(_Param,0))());
}
and so it turns out that launching a lambda on a new thread is quite difficult and beyond the scope of this question.

std::thread helper class to add thread name and stack size

I would like to make a helper class (or subclass of std::thread) to allow stack size to be set and also thread name.
If the thread is running on a platform, which does not support e.g. stack size, the number should just be ignored.
I was thinking of a "ThreadHelper", which has the extended constructor interface, and just returns a std::thread.
To be honest, I have very little experience when it comes to all the template stuff, which std::thread contains.
Right now the thread class is instantiated like:
m_thread = new std::thread(&Button::Process, this);
I would like something like:
m_thread = new ThreadHelper.Create(&Button::Process, this, stackSize, name);
Any advices are appreciated.
Thanks
Martin
Here is what you could do:
You need a wrapper around your thread start function so that you can call the appropriate functions before (and possibly after) your thread function is running. It might also be a good idea to include a try-catch block and do some error processing.
template <typename ThreadStartFnc>
struct ThreadWrapper
{
ThreadStartFnc fnc;
const char *name; // (1) Note: careful, just a pointer here, not a string. See below.
size_t priority;
size_t stack_size;
ThreadWrapper(...) // constructor here...
void operator()()
{
SetThreadName(name); // Whatever that is on your system
SetThreadPriority(priority); // dito
SetStackSize(stack_size); // not all systems allow this
try {
fnc();
}
catch(...) {
cerr << "Exception caught"; // Do exception processing here.
}
}
};
And you need a simple way to instantiate an std::thread with the wrapper "inserted", like this:
template <typename Fnc>
std::thread make_thread(const Fnc& f, const char *name, size_t priority=0, size_t stack_size=0)
{
return std::thread(ThreadWrapper<Fnc>(f, name, priority, stack_size));
}
And that is basically it. std::thread accepts a Functor object, which is what ThreadWrapper is. It calls Functor() to start the thread, which is void operator()(). This function uses the additional parameters name, priority, stack_size to set everything up and then call your function.
Enhance this with the C++11/14/17 goodies like variadic template parameters and/or lambda functions as you like.
Below is the actual wrapper function that we use (although we do not use a Functor, we use boost::bind and a static template function instead).
template <typename Fnc>
static inline void run_cstr(const Fnc &f, const char *name, DWORD priority)
{
int rc=_configthreadlocale(0);
/*
_configthreadlocale(_ENABLE_PER_THREAD_LOCALE);
setlocale(LC_ALL, "C");
*/
SetThreadName(name);
watchdog::set_thread_info(name);
::SetThreadPriority(::GetCurrentThread(), priority);
_set_se_translator(&_se_translator);
_set_invalid_parameter_handler(&my_invalid_parameter_handler);
__try {
f();
}
__except (global_seh_handler(GetExceptionCode(), GetExceptionInformation()) ) {
}
}
It sets the ThreadName for Visual Studio (SetThreadName), sets the locale, sets the thread priority, connects our software watchdog to the thread and also sets up a global Windows try/catch handler for all exceptions including access violations etc....
The global_seh_handler will be executed if any uncaught exceptions (including invalid std lib parameters) end up here. It will write a crash dump file which we use for post mortem debugging.
(1) Note: I've used a const char *name for the thread name, because I am assuming that the thread will run immediately, while the string for the thread name is still available. That is actually unsafe, if you are storing objects of type ThreadWrapper for a longer period. You'd need to change const char* to std::string then.

c++ thread pool: alternative to std::function for passing functions/lambdas to threads?

I have a thread pool that I use to execute many tiny jobs (millions of jobs, dozens/hundreds of milliseconds each). The jobs are passed in the form of either:
std::bind(&fn, arg1, arg2, arg3...)
or
[&](){fn(arg1, arg2, arg3...);}
with the thread pool taking them like this:
std::queue<std::function<void(void)>> queue;
void addJob(std::function<void(void)> fn)
{
queue.emplace_back(std::move(fn));
}
Pretty standard stuff....except that I've noticed a bottleneck where if jobs execute in a fast enough time (less than a millisecond), the conversion from lambda/binder to std::function in the addJob function actually takes longer than execution of the jobs themselves. After doing some reading, std::function is notoriously slow and so my bottleneck isn't necessarily unexpected.
Is there a faster way of doing this type of thing? I've looked into drop-in std::function replacements but they either weren't compatible with my compiler or weren't faster. I've also looked into "fast delegates" by Don Clugston but they don't seem to allow the passing of arguments along with functions (maybe I don't understand them correctly?).
I'm compiling with VS2015u3, and the functions passed to the jobs are all static, with their arguments being either ints/floats or pointers to other objects.
Have a separate queue for each of the task types - you probably don't have tens of thousands of task types. Each of these can be e.g. a static member of your tasks. Then addJob() is actually the ctor of Task and it's perfectly type-safe.
Then define a compile-time list of your task types and visit it via template metaprogramming (for_each). It'll be way faster as you don't need any virtual call fnptr / std::function<> to achieve this.
This will only work if your tuple code sees all the Task classes (so you can't e.g. add a new descendant of Task to an already running executable by loading the image from disc - hope that's a non-issue).
template<typename D> // CRTP on D
class Task {
public:
// you might want to static_assert at some point that D is in TaskTypeList
Task() : it_(tasks_.end()) {} // call enqueue() in descendant
~Task() {
// add your favorite lock here
if (queued()) {
tasks_.erase(it_);
}
}
bool queued() const { return it_ != tasks_.end(); }
static size_t ExecNext() {
if (!tasks_.empty()) {
// add your favorite lock here
auto&& itTask = tasks_.begin();
tasks_.pop_front();
// release lock
(*itTask)();
itTask->it_ = tasks_.end();
}
return tasks_.size();
}
protected:
void enqueue() const
{
// add your favorite lock here
tasks_.push_back(static_cast<D*>(this));
it_ = tasks_.rbegin();
}
private:
std::list<D*>::iterator it_;
static std::list<D*> tasks_; // you can have one per thread, too - then you don't need locking, but tasks are assigned to threads statically
};
struct MyTask : Task<MyTask> {
MyTask() { enqueue(); } // call enqueue only when the class is ready
void operator()() { /* add task here */ }
// ...
};
struct MyTask2; // etc.
template<typename...>
struct list_ {};
using TaskTypeList = list_<MyTask, MyTask2>;
void thread_pocess(list_<>) {}
template<typename TaskType, typename... TaskTypes>
void thread_pocess(list_<TaskType, TaskTypes...>)
{
TaskType::ExecNext();
thread_process(list_<TaskTypes...>());
}
void thread_process(void*)
{
for (;;) {
thread_process(TaskTypeList());
}
}
There's a lot to tune on this code: different threads should start from different parts of the queue (or one would use a ring, or several queues and either static/dynamic assignment to threads), you'd send it to sleep when there are absolutely no tasks, one could have an enum for the tasks, etc.
Note that this can't be used with arbitrary lambdas: you need to list task types. You need to 'communicate' the lambda type out of the function where you declare it (e.g. by returning `std::make_pair(retval, list_) and sometimes it's not easy. However, you can always convert a lambda to a functor, which is straightforward - just ugly.

C++ return value on concurrent queue pushing functions

After receiving answers to a previous question on logging on a different thread, I am currently at the following bit of code (note: the concurrent_queue here is from ppl, but any other concurrent_queue should work):
class concurrentFuncQueue
{
private:
typedef std::function<void()> LambdaFunction;
mutable concurrency::concurrent_queue<LambdaFunction> functionQueue;
mutable std::atomic<bool> endcond;
LambdaFunction function;
std::thread thd;
public:
concurrentFuncQueue() : endcond(false), thd([=]{
while (endcond != true)
{
if (functionQueue.try_pop( function ))
{
function(); //note: I am popping a function and adding () to execute it
}
}
}){}
~concurrentFuncQueue() { functionQueue.push([=]{ endcond = true; }); thd.join(); }
void pushFunction(LambdaFunction function) const { functionQueue.push(function); }
};
Basically the functions I push are run on a different thread sequentially (ex. a logging function) as to avoid performance issues on the main thread.
Current usage is along the following:
static concurrentFuncQueue Logger;
vector<char> outstring(256);
Logger.pushFunction([=]{ OutputDebugString(debugString.c_str()) });
Great so far. I can push functions on to a concurrent queue that will run my functions sequentially on a separate thread.
One thing I also need to have, but currently don't are return values so that ex (pseudo-code):
int x = y = 3;
auto intReturn = Logger.pushFunction([=]()->int { return x * y; });
will push x * y on to the concurrent queue, and after the pop and completion of the function (on the other thread), returns the value calculated to the caller thread.
(I understand that I'll be blocking the caller thread until the pushed function is returned. That is exactly what I want)
I get the feeling that I might have to use something along the line of std::promise, but sadly my current low understanding of them prevent me from formulating something codable.
Any ideas? Thoughts on the above C++ code and any other comments are also much welcome (please just ignore the code completely if you feel another implementation is more appropriate or solves the problem).
You should be able to use something along the lines of:
template<typename Foo>
std::future<typename std::result_of<Foo()>::type> pushFunction(Foo&& f) {
using result_type = typename std::result_of<Foo()>::type; // change to typedef if using is not supported
std::packaged_task<result_type()> t(f);
auto ret_fut = t.get_future();
functionQueue.push(std::move(t));
return ret_fut;
}
For this to work you need to make your LambdaFunction a type-erased function handler.

multithreading and classes?

Here is the issue that I'm having with multithreading. The proc needs to be static which means the only way I see that 2 threads can communicate and share data is through the global scope. This does not seem very clean nor does it feel very OO. I know I can create a static proc function in a class but that's still static.
What I'd like to for example do is have thread procs in the class somehow so that ex: I could create an MD5 checksum class and have an array of these objects, each on their own thread checking its hash, while the UI thread is not impaired by this and another class could simply keep track of the handles and wait for multiple objects before saying "Complete" or something. How is this limitation usually overcome?
You cannot avoid using a static function if you want to start a thread there. You can however (using Windows) pass the this pointer as a parameter and use it on the other side to enter the class instance.
#include <windows.h>
class Threaded {
static DWORD WINAPI StaticThreadEntry(LPVOID me) {
reinterpret_cast<Threaded*>(me)->ThreadEntry();
return 0;
}
void ThreadEntry() {
// Stuff here.
}
public:
void DoSomething() {
::CreateThread(0, 0, StaticThreadEntry, this, 0, 0);
}
};
In C++, Boost.Thread solves the problem nicely. A thread is represented by a functor, meaning that the (non-static) operator() is the thread's entry point.
For example, a thread can be created like this:
// define the thread functor
struct MyThread {
MyThread(int& i) : i(i) {}
void operator()(){...}
private:
int& i;
};
// create the thread
int j;
boost::thread thr(MyThread(j));
by passing data to the thread functor's constructor, we can pass parameters to the thread without having to rely on globals. (In this case, the thread is given a reference to the integer j declared outside the thread.)
With other libraries or APIs, it's up to you to make the jump from a (typically static) entry point to sharing non-static data.
The thread function typically takes a (sometimes optional) parameter (often of type void*), which you can use to pass instance data to the thread.
If you use this to pass a pointer to some object to the thread, then the thread can simply cast the pointer back to the object type, and access the data, without having to rely on globals.
For example, (in pseudocode), this would have roughly the same effect as the Boost example above:
void MyThreadFunc(void* params) {
int& i = *(int*)params;
...
}
int j;
CreateThread(MyThreadFunc, &j);
Or the parameter can be a pointer to an object whose (non-static) member function you wish to call, allowing you to execute a class member function instead of a nonmember.
I'm not sure I understood well... I give it a try. Are you looking for thread local storage ?
Thread creation routines usually allow you to pass a parameter to the function which will run in a new thread. This is true for both Posix pthread_create(...) and Win32 CreateThread(...). Here is a an example using Pthreads:
void* func (void* arg) {
queue_t* pqueue = (queue_t*)arg;
// pull messages off the queue
val = queue_pull(pqueue);
return 0;
}
int main (int argc, char* argv[]) {
pthread_t thread;
queue_t queue = queue_init();
pthread_create(&thread, 0, func, &queue);
// push messages on the queue for the thread to process
queue_push(&queue, 123);
void* ignored;
pthread_join(&thread, &ignored);
return 0;
}
No statics anywhere. In a C++ program you could pass a pointer to an instance of a class.