C++ threading - spawn an object (class) in loop? - c++

I need to spawn class object. For example:
class Worker {
Worker(int arg1, Object *obj);
void workLoop() { while(true) { ... } }
}
And I need spawn in loop threads with creating objects. When I do this "static", it works:
thread th1(&Worker::workLoop, Worker(args...));
thread th2(&Worker::workLoop, Worker(other args...));
But I can't spawn this in loop. I tried:
for (...) {
thread th(&Worker::workLoop, Worker(...));
threadsVector.push_back(std::move(th));
}
...but only first thread works.
Also, I have in Worker class this:
std::thread spawn() {
return std::thread(&Worker::workLoop, this);
}
I don't know how do this and why loop can't spawn my threads correctly.

try this
class Worker{
Worker(int arg, Object *obj)
void workLoop() { while(true) { ... } }
}; // do not forget the semicolon
....
vector<thread> pool;
auto func = [](Worker w){
w.workLoop();
};
// example with thread
for (int i = 0; i < 5; ++i)
pool.push_back(thread(func, Worker(5, obj)));
for (int i = 0; i < pool.size(); ++i)
pool[i].join();
// example
create a lambda expression that takes in a worker object and calls the workLoop method inside
then you can pass the lambda as an object and pass it an argument inside the thread constructor

Related

Inserting thread::id and class instance in a map

I have a class:
class IOWorker {
std::thread thread_;
boost::asio::io_service ios_;
boost::optional<boost::asio::io_service::work> work_;
Callback callback_;
// Map of thread::id and this class' instance
typedef std::map<std::thread::id, IOWorker *> IOWorkerThreadMap;
static IOWorkerThreadMap iOWorkerThreadMap;
public:
IOWorker(Callback cb);
~IOWorker();
std::thread::id getThreadId() {
return thread_.get_id();
}
// IO worker threads will call this to fetch their instance
static IOWorker* getIOWorkerInstance (void) {
auto it = iOWorkerThreadMap.find(std::this_thread::get_id());
if (it == iOWorkerThreadMap.end()) {
return nullptr;
}
return (it->second);
}
};
IOWorker::IOWorker (Callback cb) : callback_{cb}
{
work_ = boost::in_place(boost::ref(ios_));
thread_ = std::thread{[this] () {
ios_.run();
}
};
}
In a function executed by the main thread, I'm creating 10 instances of this class and inserting these into the map where thread::id is key and class instance is value.
I'm accessing this map from all the worker threads to fetch their respective class instance by looking up their thread::id in the map. The main thread accesses these instances too, to call some methods, post jobs on ios_, etc.
void startIOWorkers (Callback cb)
{
for (int i = 0; i < 10; ++i) {
IOWorker *iow = new IOWorker{cb};
std::thread::id threadId = iow->getThreadId();
IOWorkerThreadMap.insert(std::make_pair(threadId, iow));
}
}
My question is for below line:
IOWorkerThreadMap.insert(std::make_pair(threadId, iow));
My understanding (could be wrong!) is that iow and threadId in above function, will be "copied" while I'm inserting them in the map and two copies of them will exist.
I want to avoid that, therefore, I would like to know what are the better ways of having a map of thread::id and class instance in this case?
This seems way more complicated than it has to be.
If, as it appears to be the case, you only need to access the map at from thread::this_thread, the language already has a map<thread_id, T> built right in: thread_local.
class IOWorker {
std::thread thread_;
boost::asio::io_service ios_;
boost::optional<boost::asio::io_service::work> work_;
Callback callback_;
static thread_local IOWorker* this_thread_worker_;
public:
IOWorker(Callback cb);
~IOWorker();
// IO worker threads will call this to fetch their instance
static IOWorker* getIOWorkerInstance (void) {
return this_thread_worker_;
}
};
IOWorker::IOWorker (Callback cb) : callback_{std::move(cb)}
{
work_ = boost::in_place(boost::ref(ios_));
thread_ = std::thread{[this] () {
this_thread_worker_ = this;
ios_.run();
};
}
std::vector<IOWorker> startIOWorkers(Callback cb)
{
std::vector<IOWorker> launched_workers;
launched_workers.reserve(10);
for (int i = 0; i < 10; ++i) {
launched_workers.emplace_back(cb);
}
return launched_workers;
}

Attempt to use a deleted function with C++11 threads

I am trying to create a ThreadPool class which has a constructor like this
ThreadPool(size_t numberOfThreads)
: workerThreads(numberOfThreads) {
workerThreads.reserve(numberOfThreads);
for(int i =0; i < numberOfThreads; i++) {
workerThreads.emplace_back(std::thread(&ThreadPool::doJob, this));
}
}
This fails to compile for me and throws following error
error: attempt to use a deleted function
__invoke(_VSTD::move(_VSTD::get<1>(__t)), _VSTD::move(_VSTD::get<_Indices>(__t))...);
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/thread:352:5: note: in instantiation of function template specialization
'std::__1::__thread_execute<std::__1::unique_ptr<std::__1::__thread_struct, std::__1::default_delete<std::__1::__thread_struct> >, void
(ThreadPool::*)(std::__1::function<void (char *, std::__1::list<std::__1::basic_string<char>,
std::__1::allocator<std::__1::basic_string<char> > > *)>), ThreadPool *, 2>' requested here
__thread_execute(*__p, _Index());
As per other answers to similar question I also tried doing this
workerThreads.emplace_back(std::thread(&ThreadPool::doJob, std::ref(*this)));
This is reproducing same issue as well. I am compiling my code with clang c++14 on macos
Here is complete program where this reproduces
class ThreadPool {
public:
ThreadPool(size_t numberOfThreads)
: workerThreads(numberOfThreads) {
for(int i =0; i < numberOfThreads; i++) {
workerThreads[i] = std::make_shared<std::thread>(std::thread(&ThreadPool::doJob, this));
}
}
ThreadPool(const ThreadPool& tp) {
workerThreads = tp.workerThreads;
jobQueue = tp.jobQueue;
}
std::function<void(char*, std::list<std::string>*)> getNextJob() {
if(!jobQueue.empty()) {
std::function<void(char*, std::list<std::string>*)> job = jobQueue.front();
jobQueue.pop_front();
return job;
}
throw std::runtime_error("No jobs to process, thread finished");
}
void addWork(std::function<void(char*, std::list<std::string>*)> job) {
lockListMutex.lock();
jobQueue.push_back(job);
lockListMutex.unlock();
}
private:
// performs actual work
void doJob(std::function<void(char*, std::list<std::string>*)> job) {
try {
lockListMutex.lock();
getNextJob();
lockListMutex.unlock();
} catch (std::runtime_error &e) {
}
}
// a vector containing worker threads
std::vector<std::shared_ptr<std::thread>> workerThreads;
// a queue for jobs
std::list<std::function<void(char*, std::list<std::string>*)>> jobQueue;
// a mutex for synchronized insertion and deletion from list
std::mutex lockListMutex;
};
int main(int argc, char *argv[]) {
int numThreads = 1;
ThreadPool* pool = new ThreadPool(numThreads);
}
Since your doJob member function has a parameter job of type std::function<void(char*, std::list<std::string>*)>, you need to provide a corresponding argument when this function is called. Therefore, calling of this function in a new thread this way is invalid:
std::thread(&ThreadPool::doJob, this) // no argument for job passed
You either need to provide an argument, or, since the jobs should be likely dequeued from jobQueue, remove the job parameter from doJob:
void doJob()
{
... // dequeue job from jobQueue and execute it

Modifying member variables with QtConcurrent::run()?

Let's say I have a class MyClass that contains a function that is really complex and slow slowFunction() that I want to be executed in another thread, for this I'm using Qtconcurrent::run, here is a snippet:
void MyClass::startAnalysis() {
//Run slowFunction in another thread
QtConcurrent::run(this, &MyClass::slowFunction);
}
void MyClass:slowFunction() {
for(int i = 0; i < 100; i++) {
qDebug() << this << i;
}
}
The main problem that I'm facing is if slowFunction() performs any operation over a member variable of MyClass I get (eventually) a crash. Also, as in the code above, when I try to output the pointer this I also get a crash!.
Is there anything wrong with modifying member variables inside a function executed by QtConcurrent::run ?
You need to protect the access to your member variables with a QMutex.
void MyClass
{
...
private:
QMutex mutex;
}
Then whenever you access a variable used by your concurrent, you protect it with a lock.
{
QMutexLocker locker(&mutex);
// access variable
}
There is nothing wrong in modifying member variables in a thread or a QConcurrent, but you need to protect it.
In this example if I use a QFuture the class instance stays alive as long as needed.
class MyClass : QObject {
public:
void LongFunction() {
for( int count = 0; count < 5; count++ ) {
sleep( 1 );
std::cout << "Ping long!" << std::endl;
}
}
void run_c() {
QFuture<void> future = QtConcurrent::run(this, &MyClass::LongFunction);
}
};
int main(int argc, char *argv[])
{
MyClass c;
c.run_c();
}

Cast to self pointer in static method throws segfault on (derived) method call

I am trying to implement a simple thread starter class. Below you find a Simple base class implementation and 2 derived variations that are supposed to work as starters. The first one throws segfaults at static void* Threaded::run (void* self) sporadically. I suppose this might a pointer issue but I am not able to figure out why?
Does this in Threaded::start point to a wrong address or is there any other issue with my first derivation?
This is how it's used:
Thread thread (ptr_to_some_obj);
thread.start (&this_obj::callback);
thread.detach ();
Simple base class
class Threaded
{
public:
Threaded () {/* empty */}
virtual ~Threaded () {/* empty */}
/** Returns true if the thread was successfully started, false if there was an error starting the thread */
bool start ()
{
return (pthread_create (&_thread, NULL, run, this) == 0);
}
/** Implement this method in your subclass with the code which allows to gently stop execution. */
virtual void stop () = 0;
/** Will not return until the internal thread has exited. */
void wait ()
{
(void) pthread_join (_thread, NULL);
}
bool detach ()
{
return (pthread_detach (_thread) == 0);
}
protected:
/** Implement this method in your subclass with the code you want your thread to run. */
virtual void run () = 0;
static void* run (void* self)
{
((Threaded*) self) -> run ();
return NULL;
}
pthread_t _thread;
};
Derived class 1 (throws segfault at ((Threaded*) self) -> run (); above)
typedef void (*staticcall)(void*);
class Thread : public Threaded
{
public:
Thread (void* passthru)
:_call (NULL)
{
_passthru = passthru;
}
~Thread () { /* empty */ }
bool start (staticcall call)
{
_call = call;
assert (_call);
return start ();
}
void stop ()
{
// nothing
}
protected:
void run ()
{
(_call) (_passthru);
}
bool start ()
{
return Threaded::start ();
}
private:
Thread () { };
void* _passthru;
staticcall _call;
};
Derived class 2 (works, but i'd rather have Derived class 1 implementation)
typedef void (*staticcall)(void*);
class Thread2 : public Threaded
{
public:
Thread2 (void* passthru)
{
_passthru = passthru;
}
~Thread2 () { /* empty */ }
bool start (staticcall call)
{
_call = call;
assert (_call);
return start ();
}
void stop ()
{
// nothing
}
protected:
void run () { }
static void* run2 (void*)
{
(_call) (_passthru);
return NULL;
}
bool start ()
{
return (pthread_create (&_thread, NULL, run2, NULL) == 0);
}
private:
Thread2 () { };
static void* _passthru;
static staticcall _call;
};
void* Thread2::_passthru;
staticcall Thread2::_call;
As pointed out by molbdnilo:
pthread_create only queues the new thread. There are no guarantees regarding when the thread function will be called, and thread must be alive at that time.
Since I do not want to keep a list of spawned threads around I solved this with the use of pthread_cond_wait and pthread_cond_signal. The spawner will wait for a signal that is emitted by the method that runs in the thread. This way the thread creator won't destroy the thread object before the to-be-threaded method is called.
class ThreadSpawner
{
public:
ThreadSpawner ()
{
pthread_mutex_init (&MtxThreadStarter, 0);
pthread_cond_init (&CondThreadStarter, 0);
}
~ThreadSpawner ()
{
pthread_cond_destroy (&CondThreadStarter);
pthread_mutex_destroy (&MtxThreadStarter);
}
void spawn ()
{
Thread thread (pass_object);
pthread_mutex_lock (&MtxThreadStarter);
if (thread.start (&ThreadSpawner::callback))
{
// wait here for signal
pthread_cond_wait (&CondThreadStarter, &MtxThreadStarter);
thread.detach ();
}
pthread_mutex_unlock (&MtxThreadStarter);
}
static void callback (void* passthru)
{
// send signal to thread spawner
pthread_mutex_lock (&MtxThreadStarter);
pthread_cond_signal (&CondThreadStarter);
pthread_mutex_unlock (&MtxThreadStarter);
// do threaded work
}
private:
static pthread_mutex_t MtxThreadStarter;
static pthread_cond_t CondThreadStarter;
}
pthread_mutex_t ThreadSpawner::MtxThreadStarter = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t ThreadSpawner::CondThreadStarter = PTHREAD_COND_INITIALIZER;
Edit: a solution to let a thread execute as a method invokation
Well the solution I thought about in the recent discussion would work if the thread entry point was a simple function.
However, I suppose the idea is more to take advantage of an actual object, so that the thread body is actually an invokation of the body() method.
This is more tricky, since there must be a live instance of the derived class for the whole thread duration, and yet the original instance is likely to get out of scope after a start / detach sequence.
One possible (though somewhat costly) solution is to have the thread body stub create a local copy of the original instance on the stack. So the thread launcher will construct a thread object, and the thread itself will copy it.
With this system, you only need to make sure the original instance will be kept live in the interval between pthread_create and thread activation by the scheduler.
This requires a semaphore (which will be done by hand with a mutex/cond. var. pair for the 1.000.000th time, since bloody C++11 does not have one in store).
To hide this messy code inside the base class, you need to downcast the base pointer into the appropriate subclass type.
I resorted to templating the base class, though there might be smarter solutions out there. I just could not think of any.
To test the solution, I use a counter system that detects whether the original Thread instance has been deleted before the thread stub could make a local copy.
The SYNC compilation flag activates the semaphore. The expected program output is 0->0. If other numbers appear, it means some threads ran on messed-up instances.
I tested it on Ubuntu in a VM, and it seemed to work well enough.
#include <cstdlib>
#include <cstdio>
#include <cassert>
#include <thread> // sleep_for
#include <chrono> // milliseconds
#include <pthread.h>
#define SYNC // undefine this to see what happens without synchronization
typedef void *(*tEntryPoint) (void *);
#include <mutex>
#include <condition_variable>
class semaphore {
private:
std::mutex m;
std::condition_variable v;
int c;
public:
semaphore (int count = 0):c(count){}
void V()
{
#ifdef SYNC
std::unique_lock<std::mutex> l(m);
c++;
v.notify_one();
#endif
}
void P()
{
#ifdef SYNC
std::unique_lock<std::mutex> l(m);
while (c == 0) v.wait(l);
c--;
#endif
}
};
template<typename Derived>
class Threaded
{
public:
/** Returns true if the thread was successfully started, false if there was an error starting the thread */
bool start(void)
{
destructor_guard = new semaphore();
bool res = (pthread_create(&_thread, NULL, (tEntryPoint)entry_point, this) == 0);
if (res) destructor_guard->P(); // wait fot thread to start execution
delete destructor_guard;
return res;
}
/** This optional method will be executed after the thread main body */
virtual void stop() {}
/** Will not return until the internal thread has exited. */
void wait()
{
(void)pthread_join(_thread, NULL);
}
/** Will let the underlying task run independently */
bool detach()
{
return (pthread_detach(_thread) == 0);
}
private:
static void * entry_point(Derived * self)
{
Derived local_self = *self;
local_self.destructor_guard->V(); // original can be deleted
local_self.body();
local_self.stop();
return NULL;
}
pthread_t _thread;
semaphore* destructor_guard;
};
#define NUM_THREADS 9
#define REPEAT 3000
static int signature[NUM_THREADS + 1] = { 0, };
class Thread : public Threaded<Thread>
{
unsigned id;
public:
Thread(unsigned id) : id(id) {}
~Thread() { id = 0; }
void body(void)
{
signature[id%(NUM_THREADS+1)]++;
}
void stop(void)
{
std::this_thread::sleep_for(std::chrono::milliseconds(10));
signature[id%(NUM_THREADS+1)]++;
}
};
void launch_a_thread(int id)
{
Thread thread (id);
if (thread.start())
{
// thread.wait();
thread.detach();
}
}
int main(void)
{
for (unsigned i = 0; i != REPEAT*NUM_THREADS; i++) launch_a_thread(1+i%NUM_THREADS);
std::this_thread::sleep_for(std::chrono::milliseconds(100)); // leave enough time for free running threads to terminate
for (int i = 0 ; i <= NUM_THREADS ; i++) if (signature[i] != 2*REPEAT) printf ("%d -> %d\n", i, signature[i]);
return 0;
}

C++ Boost::ASIO Thread Pool issue

I just created my Thread Pool for game server, but i got one error in compiling what i didn't know how to fix.
Error :
Connection/CConnection.cpp: In lambda function:
Connection/CConnection.cpp:62:6: error: 'this' was not captured for
this lambda function
Thread Pool declaration :
class Worker {
public:
Worker(ThreadPool &s) : pool(s) { }
void operator()();
private:
ThreadPool &pool;
};
// the actual thread pool
class ThreadPool {
public:
ThreadPool(size_t);
template<class F>
void enqueue(F f);
~ThreadPool();
private:
// need to keep track of threads so we can join them
std::vector< std::unique_ptr<boost::thread> > workers;
// the io_service we are wrapping
boost::asio::io_service service;
boost::asio::io_service::work working;
friend class Worker;
};
template<class F>
void ThreadPool::enqueue(F f)
{
service.post(f);
}
Function what use it :
void CConnection::handle()
{
int i = 0;
ThreadPool pool(4);
pool.enqueue([i]
{
char * databuffer;
databuffer = new char[16];
for(int i = 0;i<16;i++)
{
databuffer[i] = 0x00;
}
databuffer[0] = 16;
databuffer[4] = 1;
databuffer[8] = 1;
databuffer[12] = 1;
asynchronousSend(databuffer, 16);
});
}
Can someone tell me where, and what is problem ?
My guess is that asynchronousSend is a function in the CConnection class. To call function in object you have to capture this:
pool.enqueue([this] { ... });
As you see I've removed the capture of i as it's not needed, since you declare a local i inside the lambda.