I'm curious as to why this would crash in around 1 runs in 4.
I have a simple class that returns a string with a thread id.
This class is called from within another class asynchronously in a lambda and returns the result. The code is as simple as I can make it - I'm still learning:
class String_Returner
{
public:
string run() const
{
return "I returned from thread "+to_string(this_thread::get_id());
}
};
class Class_Holder
{
public:
Class_Holder() : number_of_runs(10)
{
srs.resize(number_of_runs);
}
void concurrent_srs()
{
for (int i = 0; i < number_of_runs; i++)
{
results.push_back(async([&]{return srs[i].run();}));
}
for (int i = 0; i < results.size(); i++)
{
cout << i << ") " << results[i].get() << endl;
}
results.clear();
}
private:
vector<future<string>> results;
vector<String_Returner> srs;
const int number_of_runs;
};
void class_b_test()
{
Class_Holder ch;
ch.concurrent_srs();
}
I realize using async with a reference is dangerous, but I figured it'd be safe if nothing is being written. I think my error probably comes from the lambda itself. This is mainly a programme to test the functionality of async and lambdas.
So my main questions:
1) Why is it crashing?
2) What better ways are there to do this?
Why is it crashing?
results.push_back(async([&]{return srs[i].run();}));
There's nothing wrong with the reference to srs in that line; as you say, it is not being modified. But the reference to i is completely meaningless; i may no longer exist when the lambda executes, and its value will be unpredictable.
But I don't understand why you feel the need to have more than one StringReturner. The class has no state, and the run method might as well be static for all the difference it makes.
What better ways are there to do this?
Do what, exactly?
If you're going to use a lambda anyway, why not just use one that directly does what you want:
#include <string>
#include <iostream>
#include <thread>
#include <future>
#include <sstream>
#include <vector>
int main() {
std::vector<std::future<std::string>> rets;
auto f = []() {
std::ostringstream b;
b << "returned from: " << std::this_thread::get_id();
return b.str();
};
for (int i=0; i<10; i++)
rets.emplace_back(std::async(f));
for (auto & t : rets) {
t.wait();
std::cout << t.get() << "\n";
}
}
Note that the thread::id type that get_id returns is guaranteed to have an operator<<, but at least as far as I know, there's no guarantee that it's a type for which std::to_string has been overloaded.
Related
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;
}
I have a code where I have two options, define lambda out of loop to save on lambda creation overhead or define it inside a loop to keep small scope.
Is this choice critical and will make any significant difference?
What are pros and cons of this two choices?
What is best practice?
#include <iostream>
#include <string>
#include <vector>
#include <memory>
int main()
{
std::vector<std::function<void()>> functors;
auto func = [] () { std::cout << "Hello world I am doing some action"; };
//some code here
for(int i = 0; i < 100; ++i)
{
// some code here
functors.push_back(func);
// some code here
}
}
EDITED: simplified example
int main()
{
auto sum = [](const int x, const int y) { return x + y; };
for(int i = 0; i < 100; ++i)
{
std::cout << sum(i, i + 1) << std::endl;
}
}
For each lambda expression, the compiler will create a struct with operator () overloaded for it. It won't create a struct each time the control passes through a lambda, so in terms of generated code it does not matter whether you define it inside or outside the loop. Therefore, keep things local.
As a general rule, don't overthink these illusory optimization issues. Most likely, the performance bottleneck is going to be in your algorithm complexity.
I'd rather wipe out a copy construction and move construct instead by using emplace_back directly (not so useful in this case, but as a rule of thumb one should prefer it whenever possible):
#include <iostream>
#include <string>
#include <vector>
#include <memory>
int main()
{
std::vector<std::function<void()>> functors;
//some code here
for(int i = 0; i < 100; ++i)
{
// some code here
functors.emplace_back([] () { std::cout << "Hello world I am doing some action"; });
// some code here
}
}
That said, I agree with #ArmenTsirunyan and I'd avoid premature optimizations of such a type.
I'm looking for a way to store function pointers in a container like a vector. This is possible if all the functions have the same parameters but can I do if the functions have individually unique parameters?
#include <iostream>
#include <vector>
using namespace std;
void sayHi() {
cout << "Hi" << endl;
}
void sayNum(int num) {
cout << num << endl;
}
int main() {
vector<void(*)()> funcs; // vector of 0 argument functions
funcs.push_back(sayHi);
funcs.push_back(sayNum); // can't store sayNum because it takes arguments
}
Note that I can't use std::function or std::bind because VS2013 doesn't have them and I'd rather not use the boost library. The solution must be allow the possibility to iterate through the vector of function pointers and execute each one with some valid arguments.
Forgive my potential ignorance about how function pointers work, I'm very used to doing this sort of thing in Javascript in one statement :P
Made the mistake of not including as I couldn't see it mentioned in anybody's code examples but it's probably just me being bad at C++.
Not going to accept my own answer, but thought I'd post my code just in the interests of anybody who might find it useful.
#include <iostream>
#include <vector>
#include <functional>
using namespace std;
typedef std::vector<std::function<void(void)>> f_list;
f_list f1;
void _sayHi();
void _sayNum(int num);
void sayHi() {
f1.push_back(
std::bind(&_sayHi)
);
}
void sayNum(int num) {
f1.push_back(
std::bind(&_sayNum, num)
);
}
void _sayHi() {
cout << "hi" << endl;
}
void _sayNum(int num) {
cout << num << endl;
}
int main() {
sayHi();
sayNum(5);
for (int i = 0; i < f1.size(); i++) {
f1.at(i)(); // will execute desired functions
}
}
VS 2103 has std::function, std::bind and lambdas. Simply use them.
I have a program that has a class, A, that I want to run in a thread. Really, it is that A is a worker and I am going to have some number of these that are running that I want to keep track of. My problem is that my current way of doing this causes a memory leak when I check it with valgrind.
#include <iostream>
#include <thread>
#include <vector>
class A {
public:
double foobar;
A() : foobar(0) { };
A(double newfoo) : foobar(newfoo) { };
void runA(double asap) {
foobar = asap;
std::cout << "foobar is now index: " << foobar << std::endl;
}
};
int main() {
std::vector<std::thread> aThreads;
for(int i = 0; i < 10; i++) {
aThreads.push_back(std::thread(&A::runA, new A(1), i));
}
for(auto& t : aThreads) {
t.join();
}
return 0;
}
So I know that the problem is the new A(100) call, and I am really not sure how to deal with this. My actual program is much bigger, and so leaks a lot more memory, so I am wondering what I can do here. I tried creating the object in the for loop, and then using std::move() to attempt to hand said object to the thread, but that failed miserably as well. I know I have to pass in the memory address, and I know that I want the distinct objects separate as they will be doing different tasks.
How do you solve the problem of leaked memory in the case where you need to create a bunch of objects to run in their own separate threads?
Make A callable directly, then pass it by value.
#include <iostream>
#include <thread>
#include <vector>
class A {
public:
double foobar;
A() : foobar(0) { };
A(double newfoo) : foobar(newfoo) { };
void operator()(double asap) {
foobar = asap;
std::cout << "foobar is now index: " << foobar << std::endl;
}
};
int main() {
std::vector<std::thread> aThreads;
for(int i = 0; i < 10; i++) {
aThreads.push_back(std::thread(A(1), i));
}
for(auto& t : aThreads) {
t.join();
}
return 0;
}
You can save all pointers to allocated objects(in a vector, for example) and then call delete on them after your join threads.
I'm facing a weird issue : I can't reset (destruct and construct) properly an attribute containing a vector. It causes a segmentation fault when trying to access the vector.
Here is my code (witten in C++11). I think I simplified it the most possible to underscore the issue, but I might be wrong, sorry about that.
The goal would be to print two times two different (random) vectors. The first vector is working well, the second is completely failing for an unknown reason.
#include <iostream>
#include <ctime>
#include <cstdlib>
#include <vector>
class A
{
std::vector<int> n;
public :
A();
std::string toString() const;
};
A::A()
{
for (int i = 0; i < 10; i++)
n.push_back(std::rand()%10);
}
std::string A::toString() const
{
for (auto i : n)
std::cout << i << ' ';
std::cout << std::endl;
}
class B
{
A a;
public :
void resetA();
A getA() const;
};
void B::resetA()
{
a = A();
}
A B::getA() const
{
return a;
}
int main()
{
srand(time(NULL));
B b;
std::cout << b.getA().toString();
b.resetA();
std::cout << b.getA().toString();
return EXIT_SUCCESS;
}
For some reason, I would like to avoid pointers and dynamic allocation as far as possible. It would fit less with my UML conception.
Moreover, this code is working well when using simple int (no vectors).
Thank you.
Your toString() doesn't return anything, so your program has Undefined Behaviour (and, in practice, returns random garbage which is most certainly not a valid std::string object).
Perhaps you wanted to use a string stream instead?
#include <sstream>
// ...
std::string A::toString() const
{
std::ostringstream s;
for (auto i : n)
s << i << ' ';
s << '\n';
return s.str();
}
Live example.
Generally, it's a good idea to compile with as many warnings turned on as possible. This would certainly have been reported as a warning then. For this particular warning (no-void function not returning anything), I strongly suggest treating it as an error.