Here is my code:
#include <iostream>
#include <zconf.h>
#include <thread>
class JT {
public:
std::jthread j1;
JT() {
j1 = std::jthread(&JT::init, this, std::stop_token());
}
void init(std::stop_token st={}) {
while (!st.stop_requested()) {
std::cout << "Hello" << std::endl;
sleep(1);
}
std::cout << "Bye" << std::endl;
}
};
void init_2(std::stop_token st = {}) {
while (!st.stop_requested()) {
std::cout << "Hello 2" << std::endl;
sleep(1);
}
std::cout << "Bye 2" << std::endl;
}
int main() {
std::cout << "Start" << std::endl;
JT *jt = new JT();
std::jthread j2(init_2);
sleep(5);
std::cout << "Finish" << std::endl;
}
Here is the output:
Start
Hello
Hello 2
Hello
Hello 2
Hello
Hello 2
Hello
Hello 2
Hello
Hello 2
Finish
Bye 2
Hello
The problem is I could get Bye 2 message but not Bye message.
I know the passed stop_token variable results in this problem but I do not know how to pass it to a member function inside another member function.
If I'm understanding the problem correctly (my understanding being that for std::jthread(&JT::init, this) jthread wants to call JT::init(std::stop_token st, this), which isn't going to work), you probably want to use std::bind_front to give it a Callable that works.
e.g.
JT() {
j1 = std::jthread(std::bind_front(&JT::init, this));
}
According to the useful comments, I have rewritten the class code as below:
class JT {
public:
std::jthread j1;
JT() {
j1 = std::jthread(&JT::init, this);
}
void init() {
auto st = j1.get_stop_token();
while (!st.stop_requested()) {
std::cout << "Hello" << std::endl;
sleep(1);
}
std::cout << "Bye" << std::endl;
}
};
You must get the stop_token on the fly through auto st = j1.get_stop_token();.
And the revised main function:
int main() {
std::cout << "Start" << std::endl;
JT *jt = new JT();
// auto jt = std::make_unique<JT>();
std::jthread j2(init_2);
sleep(5);
std::cout << "Finish" << std::endl;
delete jt;
}
You need to delete the class object directly or use RAII (like smart pointers).
The std::stop_token must be received as parameter by the JT::init function, during the thread construction. You can use either std::bind
j1 = std::jthread{ std::bind(&JT::init, this, std::placeholders::_1) };
or, more simpler, std::bind_front as in #Hasturkun answer.
Note
Obtaining the std::stop_token after the thread has been constructed will eventually result in missing the stop request, as demonstrated bellow:
#include <thread>
#include <iostream>
using namespace std::chrono_literals;
class JT {
public:
std::jthread j1;
JT() {
j1 = std::jthread(&JT::init, this);
}
~JT() {
j1.request_stop();
j1.join();
}
void init() {
auto st = j1.get_stop_token();
while (!st.stop_requested()) {
std::this_thread::sleep_for(1ms);
std::cout << "Hello" << std::endl;
}
std::cout << "Bye" << std::endl;
}
};
int main() {
std::cout << "Start" << std::endl;
for (int i = 0; i < 1000; i++) {
JT jt;
std::this_thread::sleep_for(5ms);
}
}
Which results in:
Start
Hello
Bye
Hello
Bye
Hello
Hello
Hello
Hello
Hello
Hello
....
and program never ending. I've tested on release with gcc 12.1.0 and msvc (VS 2019 16.11.5).
Related
https://godbolt.org/z/MEsandWGe
Here's the code I'm testing, same as the above godbolt link:
#include <future>
#include <string>
#include <iostream>
#include <chrono>
#include <thread>
using namespace std::chrono_literals;
int main() {
int v = 0;
auto a1 = std::async(
std::launch::async | std::launch::deferred, [&v]() {
std::cout << "begin 1" << std::endl;
std::cout << "v = " << v << std::endl;
std::this_thread::sleep_for(100ms);
std::cout << "end 1" << std::endl;
});
auto a2 = std::async(
std::launch::async | std::launch::deferred, [&v]() {
std::cout << "begin 2" << std::endl;
std::this_thread::sleep_for(200ms);
v = 123;
std::cout << "end 2" << std::endl;
});
a2.wait();
// My understanding is a1 does not run until here?
// thus v should print 123 instead of 0 ?
a1.wait();
return 0;
}
If I remove the async policy, it works as expected.
The question is, why do I see a1 running concurrently with a2 and see v printed as 0? Does the async policy affect the behavior of deferred?
std::launch::async | std::launch::deferred means that std::async can choose which of the two policies is selected. It is implementation defined which one is used but it looks like your standard library chooses async rather than deferred.
I have multiple std::functions that are called on the main thread (not on different threads) in my app (as the result of an asynchronous HTTP requests), for example:
namespace model { struct Order{}; struct Trade{};}
std::function<void (std::string)> func1 = [](std::string http_answer)
{
std::vector<model::Order> orders = ParseOrders(http_answer);
std::cout << "Fetched " << orders.size() << " open/closed orders.");
}
std::function<void (std::string)> func2 = [](std::string http_answer)
{
std::vector<model::Trade> trades = ParseTrades(http_answer);
std::cout << "Fetched " << trades.size() << " trades.");
}
How to call process_result when the both func1 and func2 have parsed HTTP answers?
auto process_result = [](std::vector<model::Order> orders, std::vector<model::Trades> trades)
{
std::cout << "Matching orders and trades.";
};
Is there some solution with co_await or something like this?
You need some kind of synchronization point. Have not used co_await so far so this might not be what you are looking for, however in c++17 I'd go for a std::promise / std::future, maybe like this:
#include <iostream>
#include <functional>
#include <future>
std::promise<std::string> p1;
std::function<void (std::string)> func1 = [](std::string http_answer)
{
// std::vector<model::Order> orders = ParseOrders(http_answer);
// std::cout << "Fetched " << orders.size() << " open/closed orders.");
p1.set_value(http_answer);
};
std::promise<std::string> p2;
std::function<void (std::string)> func2 = [](std::string http_answer)
{
// std::vector<model::Trade> trades = ParseTrades(http_answer);
// std::cout << "Fetched " << trades.size() << " trades.");
p2.set_value(http_answer);
};
int main () {
// whenever that happens...
func1("foo");
func2("bar");
// synchronize on func1 and func2 finished
auto answer1 = p1.get_future().get();
auto answer2 = p2.get_future().get();
auto process_result = [&](/* std::vector<model::Order> orders, std::vector<model::Trades> trades */)
{
std::cout << "Matching orders and trades... " << answer1 << answer2;
};
process_result();
return 0;
}
http://coliru.stacked-crooked.com/a/3c74f00125999fb6
https://en.cppreference.com/w/cpp/thread/future
Having:
class CPU() {};
void executable() {} , inside CPU; this function is executed by a thread.
void executable(){
while(run) { // for thread
cout << "Printing the memory:" << endl;
for (auto& t : map) {
cout << t.first << " " << t.second << "\n";
}
}
}
Need to instantiate 5 threads that execute executable() function:
for (int i = 0; i < 5; i++)
threads.push_back(thread(&CPU::executable, this)); //creating threads
cout << "Synchronizing all threads...\n";
for (auto& th : threads) th.join(); //waits for all of them to finish
Now, I want to create:
void executable0 () {
while(run) {
cout << "Printing the memory:" << endl;
for (auto& t : map) {
cout << t.first << " " << t.second << "\n";
}
}
}
void executable1 () {....}
to executable4() {....} // using that five threads that I`ve done above.
How could I do? Initialize or using std:thread constructor?
Can someone give me an example to understand this process.
Thanks & regards!
Following Some programmer dude's comment, I would also advise using a standard container of std::function:
#include <iostream>
#include <thread>
#include <map>
#include <functional>
#include <vector>
class CPU {
std::vector<std::function<void()>> executables{};
std::vector<std::thread> threads{};
public:
CPU() {
executables.emplace_back([](){
std::cout << "executable0\n";
});
executables.emplace_back([](){
std::cout << "executable1\n";
});
executables.emplace_back([](){
std::cout << "executable2\n";
});
}
void create_and_exec_threads() {
for(const auto executable : executables) {
threads.emplace_back([=](){ executable(); });
}
for(auto& thread : threads) {
thread.join();
}
}
};
We create a vector holding three callbacks, which will be used to initialise threads and start them inside create_and_exec_threads method.
Please do note that, as opposed to the comment in your example, creating a std::thread with a callback passed to its contructor will not only construct the thread, but also it will start it immediately.
Additionally, the std::thread::join method does not start the the thread. It waits for it to finish.
I included the logger from boost. I'm pretty pleased how it works. Just for simplicity and the reason I don't want to use makros to often in my code, I wrap it in a class.
I now wonder if I could use the streaming operator << to write on a member function.
code
class LogWrapper{
...
//debug function
//info function
...
}
void main() {
LogWrapper log;
log.debug() << "some debug msg"; // does this exist?
log.info() << "some info msg";
}
output
[some_timestamp][debug] some debug msg
[some_timestamp][info] some info msg
Is this possible in a good practice, or is it entirely bad style?
It can be done easily like this:
#include <iostream>
class A {
public:
std::ostream &debug() const {
std::cerr << "[timestamp]" << "[DEBUG]";
return std::cerr;
}
};
int main()
{
A a;
a.debug() << "Test";
}
But the important question here is: Should we implement it in this way? In my opinion, NO!
Because you are thinking that the User of the class will print the logs like this:
int main()
{
A a;
a.debug() << "Test" << std::endl;
a.debug() << "Test2" << std::endl;
}
Output:
[timestamp][DEBUG]Test
[timestamp][DEBUG]Test2
But what if User chooses this way:
int main()
{
A a;
auto &out = a.debug();
out << "Test" << std::endl;
out << "Test2" << std::endl;
}
Output:
[timestamp][DEBUG]Test
Test2
I would highly recommend not to return stream object. You should use member functions for this purpose.
#include <iostream>
class A {
public:
static void debug(const std::string &log) {
std::cerr << "[timestamp]" << "[DEBUG]" << log << std::endl;
}
};
int main()
{
A::debug("Test 1");
A::debug("Test 2");
}
Output:
[timestamp][DEBUG]Test 1
[timestamp][DEBUG]Test 2
I am trying to make the following continuation work - but f.get() blocks. Whats wrong?
#include <iostream>
#define BOOST_THREAD_PROVIDES_FUTURE
#define BOOST_THREAD_PROVIDES_FUTURE_CONTINUATION
#include <boost/thread/future.hpp>
struct Foo {
boost::future<int> start() {
return p.get_future();
}
void finish() {
p.set_value(23);
}
boost::promise<int> p;
};
int main () {
Foo foo;
foo.start().then([](boost::future<int> f) {
std::cout << "done:" << std::endl;
std::cout << f.get() << std::endl;
});
foo.finish();
}
It'll print the "done:", so the future fires, but it'll then just "hang" on f.get() .. I am lost.
To build:
clang++ -o test8 -std=c++11 -stdlib=libc++ -lboost_thread -lboost_system \
-I/home/oberstet/boost_1_55_0 -L/home/oberstet/boost_1_55_0/stage/lib \
test8.cpp
UPDATE: The following code change will make the example work - but why? Since f2 isn't used anyway. Puzzled again.
boost::future<void> f2 = foo.start().then([](boost::future<int> f) {
std::cout << "done:" << std::endl;
std::cout << f.get() << std::endl;
});
UPDATE 2: The following, adding a launch policy launch::deferred, will also work:
foo.start().then(boost::launch::deferred, [](boost::future<int> f) {
std::cout << "done:" << std::endl;
std::cout << f.get() << std::endl;
});
and this also:
boost::future<int> start() {
boost::future<int> f = p.get_future();
f.set_deferred();
return f;
}
The problem is, your composed future is not kept around. In fact, it is a temporary and it gets destructed as soon as the statement (with .then()) ends.
Fix it:
int main () {
Foo foo;
auto f1 = foo.start();
auto f2 = f1.then([](boost::future<int> f) {
std::cout << "done:" << std::endl;
std::cout << f.get() << std::endl;
});
foo.finish();
f2.get();
}
Now it prints
done:
23
See it Live On Coliru
If you move the f2.get() before the foo.finish() it will dead lock again.