This is related to the second answer to this question.
My test code is below. I'm trying to launch a thread, and then to make it stop using the std::atomic_flag. Then the thread should output a number of loop executions and total duration, and stop.
std::atomic_flag keepRunning = ATOMIC_FLAG_INIT;
void F()
{
keepRunning.test_and_set();
long long unsigned count = 0;
const time_t start = time(nullptr);
while (keepRunning.test_and_set())
{
std::cout << '.';
++count;
}
const time_t duration = time(nullptr) - start;
std::cout << count << '\t' << duration << std::endl;
}
int main()
{
std::thread t(F);
keepRunning.clear();
t.join();
}
The problem is that the thread doesn't stop.
Why is that?
Compiler: g++ (Ubuntu 4.8.4-2ubuntu1~14.04.3) 4.8.4
OS: guest OS Ubuntu 14.04 on the macOS Sierra Ver 10.12.2 host
Compilation flags - I tried -O0 and -O4, and it didn't make any difference.
It does not stop (most of the time) because the loop in F will probably never see a cleared flag.
Assuming that the creation of a thread will take some time, keepRunning.clear() in main is likely to run first.
When F finally gets to run, it immediately sets the value and enters a loop that will never see a cleared flag and therefore never quits.
Instead of initially setting the flag value in F, a solution is to initialize it to true. However, std::atomic_flag does not let you do that because of its limited interface (this design is on purpose,std::atomic_flag is supposed to be used as a low-level building block for other primitives).
You could use a std::atomic<bool>, initialize it to true and remove the initial store(true) in F. For demo purposes, I added a sleep_for statement before clearing the flag in main.
std::atomic<bool> keepRunning{true};
void F()
{
long long unsigned count = 0;
const time_t start = time(nullptr);
while (keepRunning)
{
std::cout << '.';
++count;
}
const time_t duration = time(nullptr) - start;
std::cout << count << '\t' << duration << std::endl;
}
int main()
{
std::thread t(F);
std::this_thread::sleep_for(1s); // optional
keepRunning = false;
t.join();
}
In your F() you ignore the output from the first keepRunning.test_and_set(). Your attempt to initialize the flag there causes a race with the keepRunning.clear() statement in main(). Depending on which of these statements runs first you either get the intended behavior or have ignored clear() call and a never ending thread.
By the time F() had a chance to run, the flag should be already initialized with the correct value. Moving that initial test_and_set() into main() prevents the race:
std::atomic_flag keepRunning = ATOMIC_FLAG_INIT;
void F()
{
long long unsigned count = 0;
const time_t start = time(nullptr);
while (keepRunning.test_and_set())
{
std::cout << '.';
++count;
}
const time_t duration = time(nullptr) - start;
std::cout << count << '\t' << duration << std::endl;
}
int main()
{
keepRunning.test_and_set();
std::thread t(F);
keepRunning.clear();
t.join();
}
Now the flag is effectively only changed in main() and only "read" in F().
Related
I have some problem with st::async when is use this in other function other than Main function,
suppose, I have functions like flowing :
void printData()
{
for (size_t i = 0; i < 5; i++)
{
std::cout << "Test Function" << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
void runningAsync()
{
auto r = std::async(std::launch::async, test);
}
int main()
{
runningAsync();
std::cout << "Main Function" << std::endl;
}
the output of this code is :
Test Function
Test Function
Test Function
Test Function
Test Function
Main Function
that is not good, Main thread wait for other thread that be end.
I want runningAsync() function run in other thread and at the same time "Main Function" in main thread print on screan, this is possible with std::thread.
is that way for this running this functions an same time (concurrency)?
The reason is that std::async returns a std::future which you store in an auto variable. As soon as your future runs out of scope (at the end of runningAsync()!), its destructor blocks until the task is finished. If you do not want that, you could for example store the future in a global container.
This QUESTION answered in :
main thread waits for std::async to complete
Can I use std::async without waiting for the future limitation?
Whoever, If you store the std::future object, its lifetime will be extended to the end of main and you get the behavior you want.
void printData()
{
for (size_t i = 0; i < 5; i++)
{
std::cout << "Test Function" << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
std::future<void> runningAsync()
{
return std::async(std::launch::async, test);
}
int main()
{
auto a = runningAsync();
std::cout << "Main Function" << std::endl;
}
That's a problem because std::future's destructor may block and wait for the thread to finish. see this link for more details
I'm trying to create a concurrent code where I execute a function per second, this function prints a character and waits a second on that thread. The behaviour I expect is to print each character after another but this doesn't happen, instead, it prints all of the characters of the inner loop execution. I'm not sure if this is somewhat related to an I/O operation or whatnot.
I've also tried to create an array of threads where each thread are created on the execution of the inner loop but the behaviour repeats, even if not calling join(). What might be wrong with the code?
The following code is what I've tried to do, and I used a clock to see if it was waiting the correct amount of time
#include <iostream>
#include <thread>
#include <chrono>
#include <string>
void print_char();
int main() {
using Timer = std::chrono::high_resolution_clock;
using te = std::chrono::duration<double>;
using s = std::chrono::seconds;
te interval;
for (int i = 0; i < 100; i++) {
auto a = Timer::now();
for (int j = 0; j < i; j++) {
std::thread t(print_char);
t.join();
}
auto b = Timer::now();
interval = b-a;
std::cout << std::chrono::duration_cast<s>(interval).count();
std::cout << std::endl;
}
return 0;
}
void print_char() {
std::cout << "*";
std::this_thread::sleep_for(std::chrono::seconds(1));
}
The behaviour I expect is to print each character after another but this doesn't happen, instead, it prints all of the characters of the inner loop execution.
You need to flush the output stream in order to see the text:
std::cout << "*" << std::flush;
std::endl contains call to std::flush in it and this is why you see whole lines to be displayed once the inner loop is complete. Your threads do add the '*' characters once per second, you just don't see them being added until the stream is flushed.
Consider the code
std::thread t(print_char);
t.join();
The first line creates and start a thread. The second line immediately wait for the thread to end. That makes your program serial and not parallel. In fact, it's no different than calling the function directly instead of creating the thread.
If you want to have the thread operate in parallel and independently from your main thread, you should have the loop in the thread function itself instead. Perhaps something like
std::atomic<bool> keep_running = true;
void print_char() {
while (keep_running) {
std::cout << "*";
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
Then in the main function you just create the thread, and do something else until you want the thread to end.
std::thread t(print_char);
// Do something else...
keep_running = false;
t.join();
In regard to your current code, it's really no different than
for (int i = 0; i < 100; i++) {
auto a = Timer::now();
for (int j = 0; j < i; j++) {
print_char();
}
auto b = Timer::now();
interval = b-a;
std::cout << std::chrono::duration_cast<s>(interval).count();
std::cout << std::endl;
}
As far as I know, such use of static storage within lambda is legal. Essentially it counts number of entries into the closure:
#include <vector>
#include <iostream>
#include <algorithm>
#include <iterator>
typedef std::pair<int,int> mypair;
std::ostream &operator<< (std::ostream &os, mypair const &data) {
return os << "(" << data.first << ": " << data.second << ") ";
}
int main()
{
int n;
std::vector<mypair> v;
std::cin >> n;
v.reserve(n);
std::for_each(std::begin(v), std::end(v), [](mypair& x) {
static int i = 0;
std::cin >> x.second;
x.first = i++;
});
std::for_each(std::begin(v), std::end(v), [](mypair& x) {
std::cout << x;
});
return 0;
}
Let assume I have a container 'workers' of threads.
std::vector<std::thread> workers;
for (int i = 0; i < 5; i++) {
workers.push_back(std::thread([]()
{
std::cout << "thread #" << "start\n";
doLengthyOperation();
std::cout << "thread #" << "finish\n";
}));
}
Code in doLengthyOperation() is contained and self-sufficient operation, akin a new process creation.
Provided I join them using for_each and the stored variable in question must count number of active tasks, not just number of entries, what possible implementations for such counter are there, if I want to avoid to rely onto global variables to avoid someone else messing up with it and allowing automatic support for separate "flavors" of threads.
std::for_each(workers.begin(), workers.end(), [](std::thread &t)
{
t.join();
});
Surrounding scope would die quickly after finishing thread starts, may repeat , adding new threads to the container is possible, and that must be global variable, which I want to avoid. More of, the whole operation is a template
The best way to handle this is to capture an instance of std::atomic<int> which provides a thread safe counter. Depending on the lifetime of lambdas and the surrounding scope, you may wish to capture by reference or shared pointer.
To take your example:
std::vector<std::thread> workers;
auto counter = std::make_shared<std::atomic<int>>(0);
for (int i = 0; i < 5; i++) {
workers.push_back(std::thread([counter]()
{
std::cout << "thread #" << "start\n";
(*counter)++;
doLengthyOperation();
(*counter)--;
std::cout << "thread #" << "finish\n";
}));
}
I am trying to implement a thread safe STL vector without mutexes. So I followed through this post and implemented a wrapper for the atomic primitives.
However when I ran the code below, it displayed out Failed!twice from the below code (only two instances of race conditions) so it doesn't seem to be thread safe. I'm wondering how can I fix that?
Wrapper Class
template<typename T>
struct AtomicVariable
{
std::atomic<T> atomic;
AtomicVariable() : atomic(T()) {}
explicit AtomicVariable(T const& v) : atomic(v) {}
explicit AtomicVariable(std::atomic<T> const& a) : atomic(a.load()) {}
AtomicVariable(AtomicVariable const&other) :
atomic(other.atomic.load()) {}
inline AtomicVariable& operator=(AtomicVariable const &rhs) {
atomic.store(rhs.atomic.load());
return *this;
}
inline AtomicVariable& operator+=(AtomicVariable const &rhs) {
atomic.store(rhs.atomic.load() + atomic.load());
return *this;
}
inline bool operator!=(AtomicVariable const &rhs) {
return !(atomic.load() == rhs.atomic.load());
}
};
typedef AtomicVariable<int> AtomicInt;
Functions and Testing
// Vector of 100 elements.
vector<AtomicInt> common(100, AtomicInt(0));
void add10(vector<AtomicInt> ¶m){
for (vector<AtomicInt>::iterator it = param.begin();
it != param.end(); ++it){
*it += AtomicInt(10);
}
}
void add100(vector<AtomicInt> ¶m){
for (vector<AtomicInt>::iterator it = param.begin();
it != param.end(); ++it){
*it += AtomicInt(100);
}
}
void doParallelProcessing(){
// Create threads
std::thread t1(add10, std::ref(common));
std::thread t2(add100, std::ref(common));
// Join 'em
t1.join();
t2.join();
// Print vector again
for (vector<AtomicInt>::iterator it = common.begin();
it != common.end(); ++it){
if (*it != AtomicInt(110)){
cout << "Failed!" << endl;
}
}
}
int main(int argc, char *argv[]) {
// Just for testing purposes
for (int i = 0; i < 100000; i++){
// Reset vector
common.clear();
common.resize(100, AtomicInt(0));
doParallelProcessing();
}
}
Is there such a thing as an atomic container? I've also tested this with a regular vector<int> it didn't have any Failed output but that might just be a coincidence.
Just write operator += as:
inline AtomicVariable& operator+=(AtomicVariable const &rhs) {
atomic += rhs.atomic;
return *this;
}
In documentation: http://en.cppreference.com/w/cpp/atomic/atomic operator += is atomic.
Your example fails because below scenario of execution is possible:
Thread1 - rhs.atomic.load() - returns 10 ; Thread2 - rhs.atomic.load() - returns 100
Thread1 - atomic.load() - returns 0 ; Thread2 - atomic.load - returns 0
Thread1 - add values (0 + 10 = 10) ; Thread2 - add values (0 + 100)
Thread1 - atomic.store(10) ; Thread2 - atomic.store(100)
Finally in this case in atomic value might be 10 or 100, depends of which thread first execute atomic.store.
please note that
atomic.store(rhs.atomic.load() + atomic.load());
is not atomic
You have two options to solve it.
memoery
1) Use a mutex.
EDIT as T.C mentioned in the comments this is irrelevant since the operation here will be load() then load() then store() (not relaxed mode) - so memory order is not related here.
2) Use memory order http://bartoszmilewski.com/2008/12/01/c-atomics-and-memory-ordering/
memory_order_acquire: guarantees that subsequent loads are not moved before the current load or any preceding loads.
memory_order_release: preceding stores are not moved past the current store or any subsequent stores.
I'm still not sure about 2, but I think if the stores will not be on parallel, it will work.
I have a program which uses an io_service and several threads.
It instantiates some number of socket objects. These objects each have a strand for synchronization. All calls to async_read(), async_write(), and similar functions go through strand_.wrap(boost::bind(...)). Each object also has an int interlock_ variable that is initialized to 0.
Inside one of these functions (the on-data-receive callback), I do the following:
Class::startRead(...)
{
...
boost::asio::async_read(socket_, boost::asio::buffer(ptr, 16384), boost::asio::transfer_at_least(1),
strand_.wrap(boost::bind(&EagerConnection::on_read, this, placeholders::error, placeholders::bytes_transferred)));
}
Class::on_read(...)
{
...
startRead();
assert(0 == __sync_fetch_and_add(&interlock_, 1));
onData_();
assert(1 == __sync_fetch_and_add(&interlock_, -1));
}
Because everything is synchronized through the strand, that first assert should never fire. However, it does fire! When I check the value in GDB, the end value of interlock_ is 2, which means that two separate calls to on_read() are active at the same time.
Does this mean that boost::asio::strand is broken? (I've already checked that I don't have any re-entrancy within the completion function -- the onData_ signal handler does not re-call on_data()).
Can the "early" startRead somehow cause an immediate re-entry? (Both the semantics of async_x and strand seem to indicate it can't)
If you really, really want to see the full context of the class, it's available as a gist: https://gist.github.com/979212
I have spotted a few minor(?) issues:
Minor: The initialization order of interlock_ and strand_ is switched. Fix it by declaring interlock_ _after_ the strand_ member;
The readIn function returns no value (uninitialized data). You probably intend to return n?
Good news:
Running with valgrind turned up clear.
Running with helgrind turned up clear (but: I'm not using threads in my minimal example, I guess; Don't know about boost::asio and boost::signals internals).
I am trying to reproduce things, but my installation fails to raise the asserts when doing this.
I tacked on the following fragment at the end of the gist:
int split(std::string const &src, char ch, std::string &oLeft, std::string &oRight)
{
std::size_t pos = src.find(ch);
if (pos == std::string::npos)
{
oLeft = src;
oRight.clear();
return 1;
} else
{
oLeft = src.substr(0, pos);
oRight = src.substr(pos+1);
return 2;
}
}
namespace {
boost::asio::io_service svc;
EagerConnection c(svc);
void onconnect()
{
std::cout << "ONCONNECT" << std::endl;
const char data[] = "GET / HTTP/1.0\r\n\r\n";
c.writeOut(data, sizeof(data));
}
void ondata()
{
std::cout << "ONDATA" << std::endl;
std::ostringstream oss;
char buf[1024];
int read;
while ((read = c.readIn(buf, 1024)))
oss.write(buf, read);
std::cout << "response: " << oss.str() << std::endl;
}
void ondisconnect()
{
std::cout << "ON__DIS__CONNECT" << std::endl;
}
}
int main(int argc, char* argv[])
{
if (argc>1 && argv[1])
{
c.onConnect_.connect(&onconnect);
c.onData_.connect(&ondata);
c.onDisconnect_.connect(&ondisconnect);
c.open(argv[1]);
svc.run();
}
return 0;
}
As you can see, I'm really trying to do the SimplestThingThatCouldPossiblyWork. My connect/reconnect is working nicely (including the increasing backoff time).
I compile this with
strand: strand.cpp
g++ -Wall -Werror -o $# $^ -g -O0 -lboost_system -lboost_thread -lboost_signals -lpthread
And invoke it with
./strand 127.0.0.1:6767
I have a responding script sitting there doing (basically)
netcat -l -p 6767 -e rev
One other thing to note: the write buffer never seems to actually be sent/flushed until I interrupt the strand tester (client side). This happens regardless how large I make data... This is probably due to a step I'm missing?
Edit:
Tested identical on
ubuntu meerkat, gcc 4.4.5, boost 1.42.0
debian sid, gcc 4.5.2-8, boost 1.46.1