Creating a thread from a member class function [duplicate] - c++

This question already has answers here:
Using boost thread and a non-static class function
(5 answers)
Closed 5 years ago.
Here is my class.h
class threads_queue{
private:
boost::condition_variable the_condition_variable;
public:
//boost::atomic<bool> done;
boost::lockfree::spsc_queue<std::pair<char, std::string>> q{100};
//threads_queue() : done(false) {};
void static run_function();
void add_query(std::string, std::string);
void get_query(void);
};
& Here is class.cpp
void threads_queue::get_query(void){
std::pair<char, std::string> value;
//to do..
}
void threads_queue::add_query(std::string str, std::string work){
//to do ..
}
void run_function(){
//Here I want to create two threads
//First thread like
boost::thread producer_thread(add_query);
boost::thread consumer_thread(get_query);
producer_thread.join();
//done = true;
consumer_thread.join()
}
I'm following this example:
http://www.boost.org/doc/libs/1_54_0/doc/html/lockfree/examples.html
But the problem is when I want to create a thread I always get an error, it does not work
Here were my attempts to solve the error:
1.
boost::thread consumer_thread(&threads_queue::get_query);
I got this error:
Called object type 'void (threads_queue::*)()' is not a function or
function pointer
2.
boost::thread consumer_thread(&threads_queue::get_query, this);
I got this error:
Invalid use of 'this' outside of a non-static member function
3.
boost::thread* thr = new boost::thread(boost::bind(&threads_queue::get_query));
I got this error:
/usr/local/include/boost/bind/bind.hpp:75:22: Type 'void
(threads_queue::*)()' cannot be used prior to '::' because it has no
members
I am not how could this problem be solved, any help?
UPDATE
This topic has great discussion of the problem:
Using boost thread and a non-static class function
My main problem was I forgot to add
threads_queue::
before the run() in my cpp file, there are Mikhail comments below where were a great help: .

There is a lot wrong with your code.
Non-static members are specific to a class. In addition to the function you need to pass an instance of the class to boost::thread's constructor. This has nothing to do with threads or boost.
threads_queue should "own" the threads, and probably should be renamed to something like thread container. The whole class should at minimal be non-copyable.
Here is a complete example written by somebody other than me.
/ Copyright (C) 2009 Tim Blechmann
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//[spsc_queue_example
#include <boost/thread/thread.hpp>
#include <boost/lockfree/spsc_queue.hpp>
#include <iostream>
#include <boost/atomic.hpp>
int producer_count = 0;
boost::atomic_int consumer_count (0);
boost::lockfree::spsc_queue<int, boost::lockfree::capacity<1024> > spsc_queue;
const int iterations = 10000000;
void producer(void)
{
for (int i = 0; i != iterations; ++i) {
int value = ++producer_count;
while (!spsc_queue.push(value))
;
}
}
boost::atomic<bool> done (false);
void consumer(void)
{
int value;
while (!done) {
while (spsc_queue.pop(value))
++consumer_count;
}
while (spsc_queue.pop(value))
++consumer_count;
}
int main(int argc, char* argv[])
{
using namespace std;
cout << "boost::lockfree::queue is ";
if (!spsc_queue.is_lock_free())
cout << "not ";
cout << "lockfree" << endl;
boost::thread producer_thread(producer);
boost::thread consumer_thread(consumer);
producer_thread.join();
done = true;
consumer_thread.join();
cout << "produced " << producer_count << " objects." << endl;
cout << "consumed " << consumer_count << " objects." << endl;
}
//]

Related

How do I make a seperate thread inside a class?

I have a class foo and i put inside a member function a thread object. And i tried to initialize it like this std::thread mythread(&foo::myprint, this); inside another function. My problem is that I get the same thread::get_id with a different function foo::mycount that i need to count something. Both myprint and mycount uses this_thread::sleep_for but they don't sleep separately (something that i want to happen). I follow you up with some code example
class foo
{
void func()
{
std::thread mythread(&foo::myprint, this);
mythread.join();
}
void myprint()
{
sleep_for(1s);
cout << count << endl;
}
void mycount()
{
sleep_for(1ms);
count++;
cout << count << endl;
}
};
void main()
{
foo obj;
while(1)
{
obj.func();
obj.mycount();
}
}
I also tried putting mycount in another function with a thread object, and I don't if std::call_once affected anything, cause i used it inside the mycount function. I expected a different get_id for different functions.
Here is an example with a lambda function to start an asynchronous process.
And using std::future for synchronizing the destructor of your class with the background thread (which is counting numbers in this example).
#include <iostream>
#include <future>
#include <thread>
#include <chrono>
// dont do "using namespace std"
using namespace std::chrono_literals;
class foo
{
public:
foo() = default;
~foo()
{
// destructor of m_future will synchronize destruction with execution of the thread (waits for it to finish)
}
void func()
{
m_future = std::async(std::launch::async, [=] { myprint(); });
}
void myprint()
{
for (std::size_t n = 0; n < 5; ++n)
{
std::this_thread::sleep_for(1s);
std::cout << n << " ";
}
std::cout << "\n";
}
private:
std::future<void> m_future;
};
int main()
{
foo obj;
obj.func(); // start thread
return 0;
}

pthread_create in constructor segfault

I discovered, in this little example below, if I call pthread_create in the constructor of my struct, I get a segfault randomly on the call to pthread_mutex_lock().
And sometimes the name field is empty for the first philosopher.
If I move pthread_create to a run() function after the constructor, no segfault.
It seems the call to pthread_create happens before all the members are initialized. Shouldn't the member init list of the class be completed before the call to constructor body?
Thanks for any tips!
clang version 9.0.0 (tags/RELEASE_900/final)
Target: x86_64-apple-darwin17.7.0
Sincerely, George
#include <array>
#include <iostream>
#include <pthread.h>
#include <string>
#include <vector>
using namespace std;
struct chopstick
{
pthread_mutex_t mutex;
chopstick()
{
pthread_mutex_init(&mutex,nullptr);
}
~chopstick()
{
pthread_mutex_destroy(&mutex);
}
};
void* feed(void* data);
struct philosopher
{
pthread_t thread;
string name;
unsigned mouthfuls;
chrono::seconds sec;
chopstick &left, &right;
pthread_t& get_thread() { return thread; }
philosopher(const string &s, chopstick &l, chopstick &r): name(move(s)), left(l), right(r), mouthfuls(0)
/*
enable below to avoid segfault
{}
void run()
*/
{
pthread_create(&thread, nullptr, feed, this);
};
};
void* feed(void* data)
{
philosopher & a = *static_cast<philosopher*>(data);
while (a.mouthfuls < 20)
{
pthread_mutex_lock(&a.left.mutex);
pthread_mutex_lock(&a.right.mutex);
cout << "Apostle " << a.name << " thread id " << pthread_self()
<< " acquired a chopstick at count: " << a.mouthfuls << endl;
++a.mouthfuls;
pthread_mutex_unlock(&a.right.mutex);
pthread_mutex_unlock(&a.left.mutex);
}
return nullptr;
}
int main (int argc, char const * argv[])
{
array<string, 12> names {"John", "Thaddeus", "Simon Peter", "James", "Judhas", "Bartholomew", "Matthew", "Philip", "Simon Zealot", "Thomas", "Andrew", "James the Lesser" };
array<chopstick,names.size()> sticks;
vector<philosopher> philosophers;
for (int i=0; i+1<names.size(); ++i)
philosophers.emplace_back( names[i],sticks[i],sticks[i+1] );
philosophers.emplace_back(names[names.size()-1], sticks[0],sticks[names.size()-1]);
//for (philosopher& a: philosophers) a.run(); //<-- enable to avoid segfault
for (philosopher& a: philosophers) pthread_join(a.get_thread(), nullptr);
return 0;
}
std::vector resizes when the code does philosophers.emplace_back(), which can move the elements in memory, so that their previous addresses become invalid and the feed() function ends up accessing objects using their old invalid addresses.
A fix would be to make the philosopher class non-copyable and non-movable, and then use std::list<philosopher> or std::forward_list<philosopher> instead of std::vector<philosopher>. std::list and std::forward_list do not move elements in memory and hence are capable of storing non-copyable and non-moveable objects.
You may also like to use std::thread instead of pthread_t, and std::mutex instead of pthread_mutex_t. The std classes are non-copyable/movable which would prevent you from making this error at compile-time. Also, the code doesn't check return values of the pthread functions for errors, whereas std::thread and std::mutex do that for you.

C++: Issues in creating threads; error C2672: 'std::invoke': no matching overloaded function found

Before marking this as duplicate, I have already seen the other answers and they did not solve my issue.
I have two classes as follows:
A.cpp:
class A
{
public:
A();
int getValue()//just an example of a get method
{
return value;
}
private:
int value;
// a lot of variables
}
B.cpp:
class B
{
public:
B();
void addData(string fileName)
{
A* a = new A();
//reads the file with the fileName and does alot of stuff
//after calculation is over it adds the object to the vector
list.push_back(a);
}
void run()
{
thread t1(&B::simulate, list[0]);
thread t2(&B::simulate, list[1]);
t1.join();
t2.join();
}
private:
vector<A*> list;
void simulate(A* ptr)
{
int value = 0;
cout << "At first value is " << value << endl;
weight = ptr->getValue();
cout << "Then it becomes " << value << endl;
}
}
And then I have a simple main.cpp:
int main()
{
B* b = new B();
b->addData("File1.txt");
b->addData("File2.txt");
b->run();
return 0;
}
I am trying to create two threads by calling the method run(). However, when I try to compile I get the following error:
error C2672: 'std::invoke': no matching overloaded function found
I checked the other posts but nothing seemed to work for me. Any help would be appreciated.
P.S: I am using the following includes:
#include <thread>
#include <iostream>
and also:
using namespace std;
I am using other includes but they are irrelevant
B::simulate is a non-static member function so it requires 2 parameters - this and ptr, while you supplying only one. You should redeclare it as static since it does not access this class members anyway.

C++ std::thread and method class [duplicate]

This question already has answers here:
Start thread with member function
(5 answers)
Closed 8 years ago.
i'm trying to use a function of a class with std::thread
The follow code snippet return an error
MyClass *MyClass_ptr = new MyClass;
MyClass_ptr->MyFunction(); // Works
std::thread ThreadA(MyClass_ptr->MyFunction() ); // Error here
std::thread ThreadB(MyClass_ptr->MyOtherFunction() ); // Error here
I need to make a thread with that specific pointer to the class: MyClass_ptr
So, is there a way to use a method of that class using this specific pointer ?
If it's useful here is the full code compiled with Microsoft Visual Studio 2013
#include "stdafx.h"
#include <iostream>
#include <thread>
class MyClass
{
public:
void MyFunction();
void MyOtherFunction();
};
void MyClass::MyOtherFunction()
{
std::cout << "Inside MyOtherFunction" << std::endl;
std::cin.get();
}
void MyClass::MyFunction ()
{
std::cout << "Inside MyFunction" << std::endl;
std::cin.get();
}
int _tmain(int argc, _TCHAR* argv[])
{
MyClass *MyClass_ptr = new MyClass;
MyClass_ptr->MyFunction(); // Works
std::thread ThreadA(MyClass_ptr->MyFunction() ); // Error here
std::thread ThreadB(MyClass_ptr->MyOtherFunction() ); // Error here
delete MyClass_ptr;
MyClass_ptr = nullptr;
return 0;
}
You need to pass an object on which the member function will be called (remember, every non-static member function has an implicit this parameter) :
#include <thread>
class MyClass
{
public:
void MyFunction();
void MyOtherFunction();
};
int main()
{
MyClass *MyClass_ptr = new MyClass;
std::thread ThreadA(&MyClass::MyFunction, MyClass_ptr);
std::thread ThreadB(&MyClass::MyOtherFunction, MyClass_ptr );
}
You could use a closure.
std::thread ThreadA( [MyClass_ptr](){
MyClass_ptr->MyFunction();
});
Yes you will need to use bind. The following example is for boost bind but you could always use the C++11 version of bind.You could use it like this
boost::thread t(boost::bind(&sommeclass::someMethod, ptr_instance_of_someclass,parameters_if_any));
so in your case it will be
boost::thread ThreadA(boost::bind(MyClass::MyFunction,MyClass_ptr));

C++ thread conversion error [duplicate]

This question already has answers here:
pthread function from a class
(9 answers)
Closed 9 years ago.
I'm from Colombia so the error is in Spanish. This seems the fastest place to get an answer...
I've been trying to make a simple program that creates threads and saves the information in a vector but when I build the code the next error appears:
...Lanzador.cpp|19|error: no se puede convertir ‘void* (Hilo::*)(void*)’ a ‘void* (*)(void*)’ para el argumento ‘3’ para ‘int pthread_create(pthread_t*, const pthread_attr_t*, void* (*)(void*), void*)’|
I have three files: the header for Hilos that says:
#ifndef HILO_H
#define HILO_H
using namespace std;
class Hilo
{
public:
Hilo();
virtual ~Hilo();
void addHilo(int);
void* ImprimirHilo(void*);
protected:
private:
};
#endif // HILO_H
Hilo.cpp that says:
#include <iostream>
#include <vector>
#include <cstdlib>
#include <pthread.h>
#include <unistd.h>
#include "Hilo.h"
using namespace std;
vector<int> info (1);
Hilo::Hilo()
{
//ctor
}
Hilo::~Hilo()
{
//dtor
}
void Hilo::addHilo(int tiempo){
info.push_back(tiempo);
}
void* Hilo::ImprimirHilo(void *threadid)
{
long tid;
tid = (long) threadid;
int n =info.at(tid);
for (int i=n; i>0; i-- ){
info.at(tid)=i;
cout << "El hilo numero: " << tid << " tiene " << i <<" segundos"<< endl;
sleep(1);
}
pthread_exit(NULL);
}
And the class that has the main Lanzador.cpp
#include <iostream>
#include <cstdlib>
#include <pthread.h>
#include "Hilo.h"
using namespace std;
int main (){
Hilo h;
pthread_t threads;
int tiempo=0;
int rc;
int contador=0;
cout << "Para salir oprima 0 \n"<<endl;
cout << "Escriba el tiempo del hilo" << endl;
while (true){
cin >> tiempo;
if (tiempo>0){
contador++;
h.addHilo(tiempo);
rc = pthread_create(&threads, NULL,&h.ImprimirHilo, (void*)contador);
if (rc){
cout << "Error:unable to create thread," << rc << endl;
exit(-1);
}
}
}
pthread_exit(NULL);
}
I hope that you people can help me. Sorry for the bad English and thanks for the help
Based on the signatures mentioned in the error message you are trying to use a member function where a void() function or pointer thereof is needed: using a member function directly won't work! You need to realize that a member function apparently taking no argument actually does have a hidden argument: the this pointer! Thus, an object needs to be provided. Since you use pthread_create() there isn't any way around that: you need to come up with a normal function taking no arguments. Since the function probably needs to be declared extern "C" you can't use a static member function either.
Something doesn't seem right, however, as pthread_create() actually takes a void*(*)(void*) as argument, not a void*(*)(void) as is claimed in the error message: the void* can be used to pass information to the thread entry function, e.g., a pointer to an object which could be restored to the correct type before calling a suitable member function.
You cannot use non static methods in threading.
You will have to use the following pattern to get an instance aware method multi-threaded.
baseclass.h
class baseclass
{
int a;
static void __stdcall threaded(void* params);
}
baseclass.cpp
void __stdcall
threaded(void* params)
{
// this is your class instance
pThis = static_cast<baseclass*>(params);
printf("%d", pThis->a);
}
main.cpp
// class instance is entered as the parameter
rc = pthread_create(&threads, NULL, Hilo::ImprimirHilo, (void*)&h);