I recently asked this and this question. I wanted to use both answers I got, but when I do so, the std::async gets called synchronously.
#include <thread>
#include <chrono>
#include <iostream>
#include <future>
#include <memory>
typedef struct {
std::unique_ptr<std::future<int>> a;
} test;
int f(int id) {
std::future<int> a;
switch (id) {
case 28: {
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
break;
}
case 9: {
a = std::async(f, 28);
test t = test{ std::make_unique<std::future<int>>(std::move(a)) };
break;
}
}
std::cout << "Test For " << id << std::endl;
return 0;
}
int main() {
f(9);
}
I thought that because the std::future did not call the destructor, it would be called asynchronously, but it is not.
I want a result like this
Test For 9
# (after ~1 second)
Test for 28
but again it is doing like so:
# (after ~1 second)
Test For 28
Test For 9
Why is this not working properly?
The destructor of t is still called when the scope of the switch exits. You need to declare the scope of t to be the entire function:
int f(int id) {
test t; // declare outside switch
switch (id) {
// ...
t = test{ std::make_unique<std::future<int>>(std::move(a)) };
}
}
Here's a demo.
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 am currently practicing the use of multiple threads in C++. The program is simplified as follow. In this case, I have a global variable Obj, and within each task, a get function is processed by thread and thread detach will be called after.
In practice, get may take a great amount of time to run. If there are many tasks, get will be called repetitively (since each task has its own get function). I wonder if I can design a program where when one task has already obtained the data using get function and the data has been wrote to obj.text, then the rest of tasks can directly access or wait for the data from obj.text.
Can I use std::shared_ptr, std::future, std::async in c++ to implement this? If so, how to design the program? Any advice is greatly appreciated.
#include <chrono>
#include <future>
#include <iostream>
#include <memory>
#include <thread>
#include <vector>
using namespace std;
class Info {
public:
Info() { Ids = 10; };
int Ids;
std::string text;
};
Info Objs;
class Module {
public:
Module() {}
virtual void check(int &id){};
virtual void get(){};
};
class task1 : public Module {
public:
task1() { std::cout << "task1" << std::endl; }
void check(int &id) override {
thread s(&task1::get, this);
s.detach();
};
// The function will first do some other work (here, I use sleep to represent
// that) then set the value of Objs.text
void get() override {
// The task may take 2 seconds , So use text instead
std::this_thread::sleep_for(std::chrono::seconds(5));
Objs.text = "AAAA";
std::cout << Objs.text << std::endl;
};
};
class task2 : public Module {
public:
task2() { std::cout << "task2" << std::endl; }
void check(int &id) override {
thread s(&task2::get, this);
s.detach();
};
// The function will first do some other work (here, I use sleep to represent
// that) then set the value of Objs.text
void get() {
std::this_thread::sleep_for(std::chrono::seconds(5));
Objs.text = "AAAA";
std::cout << Objs.text << std::endl;
};
};
int main() {
std::vector<std::unique_ptr<Module>> modules;
modules.push_back(std::make_unique<task1>());
modules.push_back(std::make_unique<task2>());
for (auto &m : modules) {
m->check(Objs.Ids);
}
std::this_thread::sleep_for(std::chrono::seconds(12));
return 0;
}
It is a plain producer-consumer problem.
You have multiple “get()” producers. And did not implemented consumers yet.
First, you should have multiple “Info” for multithread. If there is only one Info, multithread programming is useless. I recommend “concurrent_queue”.
Second, “detach()” is not a good idea. You can’t manage child threads. You’d better use “join()”
My code sample follows. I used Visual Studio 2022
#include <chrono>
#include <iostream>
#include <thread>
#include <vector>
#include <concurrent_queue.h>
using namespace std;
class Info {
public:
Info() { Ids = 10; };
int Ids;
std::string text;
};
concurrency::concurrent_queue<Info> Objs;
void producer()
{
while (true) {
Info obj;
std::this_thread::sleep_for(std::chrono::seconds(5));
obj.text = "AAAA\n";
Objs.push(obj);
}
}
void consumer()
{
while (true) {
std::this_thread::sleep_for(std::chrono::seconds(1));
Info obj;
bool got_it = Objs.try_pop(obj);
if (got_it) {
std::cout << obj.text;
}
}
}
int main() {
const int NUM_CORES = 6;
std::vector<std::thread> threads;
for (int i = 0; i < NUM_CORES / 2; ++i)
threads.emplace_back(producer);
for (int i = 0; i < NUM_CORES / 2; ++i)
threads.emplace_back(consumer);
for (auto& th : threads) th.join();
}
Does std::future in c++ support polymorphism?
So, if to store child_class in future<parent_class>, can I after get it after by dynamic_cast<child_class>?
Providing you use a reference or a pointer (probably obvious since it'll fail to compile otherwise)... Yes.
#include <iostream>
#include <future>
using namespace std;
struct Parent {
virtual void a() { cout << "I am parent"; }
};
struct Child : Parent {
virtual void a() { cout << "I am child"; }
};
Child g_c; //just some global for the purposes of the example
int main() {
std::future<Parent&> p = async(launch::async, []() -> Parent& { return g_c; });
auto c = dynamic_cast<Child&>(p.get());
c.a();
return 0;
}
code result here: http://ideone.com/4Qmjvc
I am developing a C++ tool that should run transparent to main program. That is: if user simply links the tool to his program the tool will be activated. For that I need to invoke two functions, function a(), before main() gets control and function b() after main() finishes.
I can easily do the first by declaring a global variable in my program and have it initialize by return code of a(). i.e
int v = a() ;
but I cannot find a way to call b() after main() finishes?
Does any one can think of a way to do this?
The tool runs on windows, but I'd rather not use any OS specific calls.
Thank you, George
Use RAII, with a and b called in constructor/destructor.
class MyObj {
MyObj()
{
a();
};
~MyObj()
{
b();
};
};
Then just have an instance of MyObj outside the scope of main()
MyObj obj;
main()
{
...
}
Some things to note.
This is bog-standard C++ and will work on any platform
You can use this without changing ANY existing source code, simply by having your instance of MyObj in a separate compilation unit.
While it will run before and after main(), any other objects constructed outside main will also run at this time. And you have little control of the order
of your object's construction/destruction, among those others.
SOLUTION IN C:
have a look at atexit:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void bye(void)
{
printf("That was all, folks\n");
}
int main(void)
{
long a;
int i;
a = sysconf(_SC_ATEXIT_MAX);
printf("ATEXIT_MAX = %ld\n", a);
i = atexit(bye);
if (i != 0) {
fprintf(stderr, "cannot set exit function\n");
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}
http://linux.die.net/man/3/atexit
this still implies however that you have access to your main and you can add the atexit call. If you have no access to the main and you cannot add this function call I do not think there is any option.
EDIT:
SOLUTION IN C++:
as sudgested there is a c++ equivalent from std. I simply paste in here an example which i copied from the link available just below the code:
#include <iostream>
#include <cstdlib>
void atexit_handler_1()
{
std::cout << "at exit #1\n";
}
void atexit_handler_2()
{
std::cout << "at exit #2\n";
}
int main()
{
const int result_1 = std::atexit(atexit_handler_1);
const int result_2 = std::atexit(atexit_handler_2);
if ((result_1 != 0) or (result_2 != 0)) {
std::cerr << "Registration failed\n";
return EXIT_FAILURE;
}
std::cout << "returning from main\n";
return EXIT_SUCCESS;
}
http://en.cppreference.com/w/cpp/utility/program/atexit
Isn't any global variable constructed before main and destructed afterward? I made a test struct whose constructor is called before main and the destructor afterward.
#include <iostream>
struct Test
{
Test() { std::cout << "Before main..." << std::endl; }
~Test() { std::cout << "After main..." << std::endl; }
};
Test test;
int main()
{
std::cout << "Returning now..." << std::endl;
return 0;
}
If you're happy to stick with a single compiler and non-standard C/C++, then GCC's __attribute__((constructor)) and __attribute__((destructor)) might be of use:
#include <stdio.h>
void __attribute__((constructor)) ctor()
{
printf("Before main()\n");
}
void __attribute__((destructor)) dtor()
{
printf("After main()\n");
}
int main()
{
printf("main()\n");
return 0;
}
Result:
Before main()
main()
After main()
Alternatively to the destructor, you can use atexit() in a similar manner - in C++, you do not need to have access to main() to register atexit there. You can do that as well it in your a() - for example:
void b(void) {
std::cout << "Exiting.\n";
}
int a(void) {
std::cout << "Starting.\n";
atexit(b);
return 0;
}
// global in your module
int i = a();
That being said, I'd also prefer the global C++ class object, which will call the b() stuff in its destructor.
Firstly,I want to inform you that my overall/main target is to execute certain functions using their function name(string) as an argument,I defined a function as below:
(I want to generate a unique number for each string data that I inserted as argument to a function)
#include <iostream>
#include <string>
#include <hash_set>
using namespace std;
void Func_Execution(string &s){
int k=stdext::hash_value(s);
#if(_MSC_VER ==1500)
switch (k)
{
case -336300864: GETBATTERYCALLSIGNS();
break;
case -1859542241:GETGUNIDS();
break;
case 323320073:Foo(); // here int k=323320073 for string s="Foo"
break;
case 478877555:Bar();
break;
defalut :Exit();
break;
}
#endif
}
Here I call Func_Execution function as below:
void main(){
string s="Foo";
Func_Execution(s);
}
I want to know that is there any efficient(considering perfomance/time consuming) and effective mechanism to generate a unique numerical value for certain string(character pattern) rather than using stdext::hash_value() function?(Also notice I want to implement switch-case too)
Have you considered something like
#include <functional>
#include <iostream>
#include <unordered_map>
#include <string>
using std::cout;
using std::endl;
using std::function;
using std::string;
using std::unordered_map;
class Registry {
public:
static void Execute(const string& function) {
if (functions_.find(function) != functions_.end()) {
functions_[function]();
}
}
static int Register(const string& function_name, function<void()> f) {
functions_.emplace(function_name, f);
return functions_.size();
}
static void Dump() {
for (auto& i : functions_) {
cout << i.first << endl;
}
}
private:
Registry() {};
static unordered_map<string, function<void()>> functions_;
};
unordered_map<string, function<void()>> Registry::functions_;
#define REGISTER_FUNCTION(F) \
namespace { \
const int REGISTERED__##F = Registry::Register(#F, &F); \
}
void foo() {
cout << "foo" << endl;
}
REGISTER_FUNCTION(foo);
void bar() {
cout << "bar" << endl;
}
REGISTER_FUNCTION(bar);
int main() {
Registry::Execute("foo");
Registry::Execute("foo");
Registry::Execute("unknown");
Registry::Dump();
return 0;
}
It should serve well for your use case. I just hacked it together, there's probably a bug somewhere, but it compiles and runs (c++11).
Don't use hash_value() for fingerprinting (which is what you are describing). If you really know all your possible strings ahead of time, use your own perfect hash function and then measure the results to see if it is worth it.