I am trying to get the code example from there to work:
https://solarianprogrammer.com/2012/10/17/cpp-11-async-tutorial/
int twice(int m){
return 2*m;
}
int main(){
std::vector< std::future<int> > futures;
for(int i=0;i<10;++i){
futures.push_back(std::async(twice,i));
}
for(auto &e:futures){
std::cout << e.get() << std::endl;
}
return 0;
}
This code results in:
terminate called after throwing an instance of 'std::system_error'
what(): Unknown error -1
I am using these flags for compilation:
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -pthread")
The code below results in the same error (we just instantiate some minimal and unused object):
int twice(int m){
return 2*m;
}
class Foo {
public:
Foo();
};
Foo::Foo(){}
int main(){
Foo foo;
std::vector< std::future<int> > futures;
for(int i=0;i<10;++i){
futures.push_back(std::async(twice,i));
}
for(auto &e:futures){
std::cout << e.get() << std::endl;
}
return 0;
}
This ends up with the similar results:
terminate called after throwing an instance of 'std::system_error'
what(): Unknown error -1
But this works fine (i.e. prints: 0 2 4 ... 18 as expected):
int twice(int m){
return 2*m;
}
int main(){
nsp::Foo foo; // <---- difference here !
std::vector< std::future<int> > futures;
for(int i=0;i<10;++i){
futures.push_back(std::async(twice,i));
}
for(auto &e:futures){
std::cout << e.get() << std::endl;
}
return 0;
}
nsp::Foo is now defined/declared in another library (but with the same code). This library in compiled in the same CMakeLists.txt folder with the same compilation flags. And the executable links to it.
What is going on ?
Related
class test
{
void thread1()
{
int i = 0;
while(true){
for(unsigned int k = 0;k < mLD.size(); k++ )
{
mLD[k] = i++;
}
}
}
void thread2()
{
std::cout << "thread2 address : " << &mLD << "\n";
C();
}
void B()
{
std::cout << "B address : " << &mLD << "\n";
for(unsigned int k = 0;k < mLD.size(); k++ )
{
if(mLD[k]<=25)
{
}
}
}
void C()
{
B();
std::cout << "C address : " << &mLD << "\n";
double distance = mLD[0]; // <---- segmetation fault
}
std::array<double, 360> mLD;
};
cout result --->
thread2 address : 0x7e807660
B address : 0x7e807660
C address : 0x1010160 (sometimes 0x7e807660 )
Why mLD's address changed ....?
even i change std::array to std::array<std::atomic<double>360>, the result is the same.
Most probably, the object you referred is destroyed at the point of call to C, which points to a synchronization issue. You need to extend the lifetime of the object referred by thread(s), until the threads done executing their routine. To accomplish this, you can have something like this;
#include <thread>
#include <array>
#include <iostream>
struct foo{
void callback1(){
for(auto & elem: storage){
elem += 5;
}
}
void callback2(){
for(const auto & elem: storage){
std::cout << elem << std::endl;
}
}
std::array<double, 300> storage;
};
int main(void){
foo f;
std::thread t1 {[&f](){f.callback1();}};
std::thread t2 {[&f](){f.callback2();}};
// wait until both threads are done executing their routines
t1.join();
t2.join();
return 0;
}
The instance of foo, f lives in scope of main() function, so its' lifetime is defined by from the line it defined to end of the main's scope. By joining both threads, we block main from proceeding further until both threads are done executing their callback functions, hence the lifetime of f extended until callbacks are done.
The second issue is, the code needs synchronization primitives, because storage variable is shared between two independent execution paths. The final code with proper synchronization can look like this;
#include <thread>
#include <array>
#include <iostream>
#include <mutex>
struct foo{
void callback1(){
// RAII style lock, which invokes .lock() upon construction, and .unlock() upon destruction
// automatically.
std::unique_lock<std::mutex> lock(mtx);
for(auto & elem: storage){
elem += 5;
}
}
void callback2(){
std::unique_lock<std::mutex> lock(mtx);
for(const auto & elem: storage){
std::cout << elem << std::endl;
}
}
std::array<double, 300> storage;
// non-reentrant mutex
mutable std::mutex mtx;
};
int main(void){
foo f;
std::thread t1 {[&f](){f.callback1();}};
std::thread t2 {[&f](){f.callback2();}};
// wait until both threads are done executing their routines
t1.join();
t2.join();
return 0;
}
I am trying to construct a std::thread with a member function that takes no arguments and returns void. I can't figure out any syntax that works - the compiler complains no matter what. What is the correct way to implement spawn() so that it returns a std::thread that executes test()?
#include <thread>
class blub {
void test() {
}
public:
std::thread spawn() {
return { test };
}
};
#include <thread>
#include <iostream>
class bar {
public:
void foo() {
std::cout << "hello from member function" << std::endl;
}
};
int main()
{
std::thread t(&bar::foo, bar());
t.join();
}
EDIT:
Accounting your edit, you have to do it like this:
std::thread spawn() {
return std::thread(&blub::test, this);
}
UPDATE: I want to explain some more points, some of them have also been discussed in the comments.
The syntax described above is defined in terms of the INVOKE definition (§20.8.2.1):
Define INVOKE (f, t1, t2, ..., tN) as follows:
(t1.*f)(t2, ..., tN) when f is a pointer to a member function of a class T and t1 is an object of type T or a reference to an object of
type T or a reference to an object of a type derived from T;
((*t1).*f)(t2, ..., tN) when f is a pointer to a member function of a class T and t1 is not one of the types described in the previous
item;
t1.*f when N == 1 and f is a pointer to member data of a class T and t 1 is an object of type T or a
reference to an object of type T or a reference to an object of a
type derived from T;
(*t1).*f when N == 1 and f is a pointer to member data of a class T and t 1 is not one of the types described in the previous item;
f(t1, t2, ..., tN) in all other cases.
Another general fact which I want to point out is that by default the thread constructor will copy all arguments passed to it. The reason for this is that the arguments may need to outlive the calling thread, copying the arguments guarantees that. Instead, if you want to really pass a reference, you can use a std::reference_wrapper created by std::ref.
std::thread (foo, std::ref(arg1));
By doing this, you are promising that you will take care of guaranteeing that the arguments will still exist when the thread operates on them.
Note that all the things mentioned above can also be applied to std::async and std::bind.
Since you are using C++11, lambda-expression is a nice&clean solution.
class blub {
void test() {}
public:
std::thread spawn() {
return std::thread( [this] { this->test(); } );
}
};
since this-> can be omitted, it could be shorten to:
std::thread( [this] { test(); } )
or just (deprecated)
std::thread( [=] { test(); } )
Here is a complete example
#include <thread>
#include <iostream>
class Wrapper {
public:
void member1() {
std::cout << "i am member1" << std::endl;
}
void member2(const char *arg1, unsigned arg2) {
std::cout << "i am member2 and my first arg is (" << arg1 << ") and second arg is (" << arg2 << ")" << std::endl;
}
std::thread member1Thread() {
return std::thread([=] { member1(); });
}
std::thread member2Thread(const char *arg1, unsigned arg2) {
return std::thread([=] { member2(arg1, arg2); });
}
};
int main(int argc, char **argv) {
Wrapper *w = new Wrapper();
std::thread tw1 = w->member1Thread();
std::thread tw2 = w->member2Thread("hello", 100);
tw1.join();
tw2.join();
return 0;
}
Compiling with g++ produces the following result
g++ -Wall -std=c++11 hello.cc -o hello -pthread
i am member1
i am member2 and my first arg is (hello) and second arg is (100)
#hop5 and #RnMss suggested to use C++11 lambdas, but if you deal with pointers, you can use them directly:
#include <thread>
#include <iostream>
class CFoo {
public:
int m_i = 0;
void bar() {
++m_i;
}
};
int main() {
CFoo foo;
std::thread t1(&CFoo::bar, &foo);
t1.join();
std::thread t2(&CFoo::bar, &foo);
t2.join();
std::cout << foo.m_i << std::endl;
return 0;
}
outputs
2
Rewritten sample from this answer would be then:
#include <thread>
#include <iostream>
class Wrapper {
public:
void member1() {
std::cout << "i am member1" << std::endl;
}
void member2(const char *arg1, unsigned arg2) {
std::cout << "i am member2 and my first arg is (" << arg1 << ") and second arg is (" << arg2 << ")" << std::endl;
}
std::thread member1Thread() {
return std::thread(&Wrapper::member1, this);
}
std::thread member2Thread(const char *arg1, unsigned arg2) {
return std::thread(&Wrapper::member2, this, arg1, arg2);
}
};
int main() {
Wrapper *w = new Wrapper();
std::thread tw1 = w->member1Thread();
tw1.join();
std::thread tw2 = w->member2Thread("hello", 100);
tw2.join();
return 0;
}
Some users have already given their answer and explained it very well.
I would like to add few more things related to thread.
How to work with functor and thread.
Please refer to below example.
The thread will make its own copy of the object while passing the object.
#include<thread>
#include<Windows.h>
#include<iostream>
using namespace std;
class CB
{
public:
CB()
{
cout << "this=" << this << endl;
}
void operator()();
};
void CB::operator()()
{
cout << "this=" << this << endl;
for (int i = 0; i < 5; i++)
{
cout << "CB()=" << i << endl;
Sleep(1000);
}
}
void main()
{
CB obj; // please note the address of obj.
thread t(obj); // here obj will be passed by value
//i.e. thread will make it own local copy of it.
// we can confirm it by matching the address of
//object printed in the constructor
// and address of the obj printed in the function
t.join();
}
Another way of achieving the same thing is like:
void main()
{
thread t((CB()));
t.join();
}
But if you want to pass the object by reference then use the below syntax:
void main()
{
CB obj;
//thread t(obj);
thread t(std::ref(obj));
t.join();
}
I'm trying to use CUDA with objects, this is a little test code i put together to try out things, but i ran into a problem. When i'm doing anything to the device version of the variable, the copy back to the host fails with "cuda Error Ilegal Address", but if i just copy the code to the device and back it works.
If i comment out the printf... line, it the works.
class A {
public:
int s;
};
__device__ A *d_a;
__global__ void MethodA() {
printf("%d\n", d_a->s);
}
int main() {
A *a = new A();
a->s = 10;
cudaError e;
e = cudaMalloc((void**)&d_a, sizeof(A));
e = cudaMemcpy(d_a, a, sizeof(A), cudaMemcpyHostToDevice);
MethodA << <1, 1 >> > ();
e = cudaMemcpy(a, d_a, sizeof(A), cudaMemcpyDeviceToHost);
std::cout << cudaGetErrorName(e) << std::endl;
delete(a);
std::getchar();
return 0;
}
Use of the __device__ variable is causing difficulty. It is intended to be used for static allocations, known at compile time.
Your methodology would be simplified if you used an ordinary host-based pointer, pointing to a dynamic allocation created at runtime (which you are doing anyway), and then pass that host-based pointer to the device, via a kernel parameter.
Some problems with your approach:
You are using an incorrect API for modifying a __device__ variable. We don't use cudaMemcpy. We use cudaMemcpyToSymbol, etc.
You are not allowed to take the address of a device entity in host code:
e = cudaMalloc((void**)&d_a, sizeof(A));
^
cudaMalloc expects to store the allocated pointer value in host memory, not in device memory. It will point to a location in device memory, but it should be stored in a host variable.
If you want to stay with your method, the following modifications should make it correct:
$ cat t89.cu
#include <iostream>
#include <stdio.h>
class A {
public:
int s;
};
__device__ A *d_a;
__global__ void MethodA() {
printf("%d\n", d_a->s);
}
int main() {
A *a = new A();
a->s = 10;
A *temp_d_a;
cudaMalloc((void**)&temp_d_a, sizeof(A));
cudaMemcpy(temp_d_a, a, sizeof(A), cudaMemcpyHostToDevice);
cudaMemcpyToSymbol(d_a, &temp_d_a, sizeof(A *));
MethodA << <1, 1 >> > ();
cudaMemcpy(a, temp_d_a, sizeof(A), cudaMemcpyDeviceToHost);
std::cout << cudaGetErrorString(cudaGetLastError()) << std::endl;
cudaFree(temp_d_a);
delete(a);
return 0;
}
$ nvcc t89.cu -o t89
$ cuda-memcheck ./t89
========= CUDA-MEMCHECK
10
no error
========= ERROR SUMMARY: 0 errors
$
EDIT: Regarding my previous statement:
Your methodology would be simplified if you used an ordinary host-based pointer, pointing to a dynamic allocation created at runtime (which you are doing anyway), and then pass that host-based pointer to the device, via a kernel parameter.
and asked about in the comments below, here is a worked example showing that approach:
$ cat t89.cu
#include <iostream>
#include <stdio.h>
class A {
public:
int s;
};
__global__ void MethodA(A *a) {
printf("%d\n", a->s);
}
int main() {
A *a = new A();
a->s = 10;
A *d_a; // an ordinary host-based pointer
cudaMalloc((void**)&d_a, sizeof(A)); //dynamic allocation created at runtime
cudaMemcpy(d_a, a, sizeof(A), cudaMemcpyHostToDevice);
MethodA << <1, 1 >> > (d_a); // passed to kernel via parameter
cudaMemcpy(a, d_a, sizeof(A), cudaMemcpyDeviceToHost);
std::cout << cudaGetErrorString(cudaGetLastError()) << std::endl;
cudaFree(d_a);
delete(a);
return 0;
}
$ nvcc -o t89 t89.cu
$ cuda-memcheck ./t89
========= CUDA-MEMCHECK
10
no error
========= ERROR SUMMARY: 0 errors
$
I am trying to change the behavior of a future object based on user input.
#include <iostream>
#include <future>
//=======================================================================================!
struct DoWork
{
DoWork(int cycles, int restTime) : _cycles(cycles), _restTime(restTime), _stop(false)
{
}
void operator () ()
{
for(int i = 0 ; i < _cycles; ++i)
{
std::this_thread::sleep_for(std::chrono::milliseconds(_restTime));
if(_stop)break;
doTask();
}
}
void stop()
{
_stop = true;
}
private:
void doTask()
{
std::cout << "doing task!" << std::endl;
}
private:
int _cycles;
int _restTime;
bool _stop;
};
//=======================================================================================!
int main()
{
DoWork doObj(50, 500);
std::future<int> f = std::async(std::launch::async, doObj);
std::cout << "Should I stop work ?" << std::endl;
std::cout << "('1' = Yes, '2' = no, 'any other' = maybe)" << std::endl;
int answer;
std::cin >> answer;
if(answer == 1) doObj.stop();
std::cout << f.get() << std::endl;
return 0;
}
//=======================================================================================!
However this does not stop the execution of the future object. How do I change the behavior of the doObj after I have created the future object?
You have a few problems. First, your function object doesn't actually return int, so std::async will return a std::future<void>. You can fix this either by actually returning int from DoWork::operator(), or by storing the result from async in a std::future<void> and not trying to print it.
Second, std::async copies its arguments if they aren't in reference wrappers, so the doObj on the stack is not going to be the same instance of DoWork that is being used by the asynchronous thread. You can correct this by passing doObj in a reference wrapper a la std::async(std::launch::async, std::ref(doObj)).
Third, both the main thread and the asynchronous thread are simultaneously accessing DoWork::_stop. This is a data race and means the program has undefined behavior. The fix is to protect accesses to _stop with a std::mutex or to make it a std::atomic.
Altogether, program should look like (Live at Coliru):
#include <iostream>
#include <future>
//=======================================================================================!
struct DoWork
{
DoWork(int cycles, int restTime) : _cycles(cycles), _restTime(restTime), _stop(false)
{
}
int operator () ()
{
for(int i = 0 ; i < _cycles; ++i)
{
std::this_thread::sleep_for(std::chrono::milliseconds(_restTime));
if(_stop) return 42;
doTask();
}
return 13;
}
void stop()
{
_stop = true;
}
private:
void doTask()
{
std::cout << "doing task!" << std::endl;
}
private:
int _cycles;
int _restTime;
std::atomic<bool> _stop;
};
//=======================================================================================!
int main()
{
DoWork doObj(50, 500);
std::future<int> f = std::async(std::launch::async, std::ref(doObj));
std::cout << "Should I stop work ?" << std::endl;
std::cout << "('1' = Yes, '2' = no, 'any other' = maybe)" << std::endl;
int answer;
std::cin >> answer;
if(answer == 1) doObj.stop();
std::cout << f.get() << std::endl;
}
//=======================================================================================!
I am trying to create a Runnable interface in c++11 using packaged_task, with child class overriding run() function. I don't know why this code is not compiling. Its giving error related to type argument.
/usr/include/c++/4.8.1/functional:1697:61: error: no type named ‘type’ in ‘class std::result_of()>’
typedef typename result_of<_Callable(_Args...)>::type result_type;
Below is my code snippet. Could someone plz give me some information on this error and whether implementing Runnable this way is a right way to proceed ?
class Runnable {
public:
explicit Runnable() {
task_ = std::packaged_task<int()>(&Runnable::run);
result_ = task_.get_future();
std::cout << "starting task" << std::endl;
}
virtual int run() = 0;
int getResult() {
task_();
return result_.get();
}
virtual ~Runnable() {
std::cout << "~Runnable()" << std::endl;
}
private:
std::future<int> result_;
std::packaged_task<int()> task_;
};
class foo : public Runnable {
int fib(int n) {
if (n < 3) return 1;
else return fib(n-1) + fib(n-2);
}
public:
explicit foo(int n) : n_(n) {}
int run() {
cout << "in foo run() " << endl;
int res = fib(n_);
cout << "done foo run(), res = " << res << endl;
return res;
}
~foo() {}
private:
int n_;
};
int main(int argc, char*argv[]) {
stringstream oss;
oss << argv[1];
int n;
oss >> n;
shared_ptr<foo> obj(new foo(n));
obj->run();
cout << "done main" << endl;
return 0;
}