C++11 std::threads not exiting - c++11

Could you please check the following code which is not exiting even after condition becomes false?
I'm trying to print numbers from 1 to 10 by first thread, 2 to 20 by second thread likewise & I have 10 threads, whenever count reaches to 100, my program should terminate safely by terminating all threads. But that is not happening, after printing, it stuck up and I don't understand why?
Is there any data race? Please guide.
#include<iostream>
#include<vector>
#include<thread>
#include<mutex>
#include<condition_variable>
std::mutex mu;
int count=1;
bool isDone = true;
std::condition_variable cv;
void Print10(int tid)
{
std::unique_lock<std::mutex> lock(mu);
while(isDone){
cv.wait(lock,[tid](){ return ((count/10)==tid);});
for(int i=0;i<10;i++)
std::cout<<"tid="<<tid<<" count="<<count++<<"\n";
isDone = count<100;//!(count == (((tid+1)*10)+1));
std::cout<<"tid="<<tid<<" isDone="<<isDone<<"\n";
cv.notify_all();
}
}
int main()
{
std::vector<std::thread> vec;
for(int i=0;i<10;i++)
{
vec.push_back(std::thread(Print10,i));
}
for(auto &th : vec)
{
if(th.joinable())
th.join();
}
}

I believe the following code should work for you
#include<iostream>
#include<vector>
#include<thread>
#include<mutex>
#include<condition_variable>
using namespace std;
mutex mu;
int count=1;
bool isDone = true;
condition_variable cv;
void Print10(int tid)
{
unique_lock<std::mutex> lock(mu);
// Wait until condition --> Wait till count/10 = tid
while(count/10 != tid)
cv.wait(lock);
// Core logic
for(int i=0;i<10;i++)
cout<<"tid="<<tid<<" count="<<count++<<"\n";
// Release the current thread thus ensuring serailization
cv.notify_one();
}
int main()
{
std::vector<std::thread> vec;
for(int i=0;i<10;i++)
{
vec.push_back(std::thread(Print10,i));
}
for(auto &th : vec)
{
if(th.joinable())
th.join();
}
return 0;
}

Related

Why does my code giving me "mismatch in formal parameter list"?

I am trying to transfer the elements from a source stack to a destination stack. And for that i am using some variables and making sure that get transfered into the destination stack in the same order as they were in the source stack. I wrote the following code
#include <iostream>
#include <stack>
using namespace std;
template <typename S>
void transferByVar(stack<S> &source, stack<S> &dest)
{
int var = 0;
S topVal;
if (source.empty())
return;
else if (source.size() == 1)
{
dest.push(source.top());
source.pop();
}
int size = source.size();
while (count != size)
{
topVal = source.top();
source.pop();
while (source.size() != count)
{
dest.push(source.top());
source.pop();
}
source.push(topVal);
while (!dest.empty())
{
source.push(dest.top());
dest.pop();
}
++count;
}
}
int main()
{
stack <int> s1;
stack<int> s2;
s1.push(0);
s1.push(1);
s1.push(2);
s1.push(3);
s1.push(4);
s1.push(5);
s1.push(6);
s1.push(7);
s1.push(8);
s1.push(9);
transferByVar(s1, s2);
int size = s2.size();
for (int i = 0; i < size; i++)
{
cout << s2.top() << " ";
s2.pop();
}
return 0;
}
but it gives me an error of C2563: mismatch of formal parameter list. What can I do to fix this?

no data while cpu profiling - visual studio

i tried to profile performance of my code, and thats what i get:
i took a code from microsoft docs from topic about profiling:
#include <iostream>
#include <limits>
#include <mutex>
#include <random>
#include <functional>
//.cpp file code:
static constexpr int MIN_ITERATIONS = std::numeric_limits<int>::max() / 1000;
static constexpr int MAX_ITERATIONS = MIN_ITERATIONS + 10000;
long long m_totalIterations = 0;
std::mutex m_totalItersLock;
int getNumber()
{
std::uniform_int_distribution<int> num_distribution(MIN_ITERATIONS, MAX_ITERATIONS);
std::mt19937 random_number_engine; // pseudorandom number generator
auto get_num = std::bind(num_distribution, random_number_engine);
int random_num = get_num();
auto result = 0;
{
std::lock_guard<std::mutex> lock(m_totalItersLock);
m_totalIterations += random_num;
}
// we're just spinning here
// to increase CPU usage
for (int i = 0; i < random_num; i++)
{
result = get_num();
}
return result;
}
void doWork()
{
std::wcout << L"The doWork function is running on another thread." << std::endl;
auto x = getNumber();
}
int main()
{
std::vector<std::thread> threads;
for (int i = 0; i < 10; ++i) {
threads.push_back(std::thread(doWork));
std::cout << "The Main() thread calls this after starting the new thread" << std::endl;
}
for (auto& thread : threads) {
thread.join();
}
return 0;
}
, and still i'm getting different output (or no output actually). Can someone help me pls? I'm trying to do that on Visual Studio Community 2019

C++ class with static mutex & racing condition

I have this C++ class with static mutex as private member of the class to protect cout in another public function of the class. But when I call object of the class from two threads I get a racing condition. Not sure why ?
class ThreadSafePrint
{
public:
void myprint(int threadNumber)
{
std::lock_guard<std::mutex> gaurd(mymutex);
cout <<"Thread " << threadNumber << endl;
}
private:
static std::mutex mymutex;
};
std::mutex ThreadSafePrint::mymutex;
int main()
{
ThreadSafePrint obj;
std::vector<std::thread> workers;
int threadNumber;
// create 2 threads and pass a number
for(int i=0; i<2;++i)
{
// threadNumber = 0 for 1st thread
if(i==0)
{
threadNumber = i;
}
// threadNumber = 1 for 2nd thread
if(i==1)
{
threadNumber = i;
}
workers.push_back(std::thread([&obj,&threadNumber]()
{
obj.myprint(threadNumber);
}));
}
// join all threads
std::for_each(workers.begin(), workers.end(),[](std::thread & th)
{
th.join();
});
return 0;
}
Here are some results:
>> ./mythreads
Thread 1
Thread 1
>> ./mythreads
Thread 0
Thread 0
You capture a reference to the local variable threadNumber in two worker threads, access it in both threads, and mutate it in the main thread without any synchronisation. This is indeed a race condition. Capture by value instead.
workers.push_back(std::thread([&obj, threadNumber]()
You have to capture threadNumber by value, not by reference.
Exchange:
workers.push_back(std::thread([&obj,&threadNumber]()
by
workers.push_back(std::thread([&obj,threadNumber]()
Otherwise the variable threadNumber will be altered also for the first thread, by the second loop run.
#include <iostream>
#include <thread>
#include <mutex>
#include <vector>
#include <algorithm>
class ThreadSafePrint
{
public:
void myprint(int threadNumber)
{
std::lock_guard<std::mutex> gaurd(mymutex);
std::cout <<"Thread " << threadNumber << std::endl;
}
private:
static std::mutex mymutex;
};
std::mutex ThreadSafePrint::mymutex;
int main()
{
ThreadSafePrint obj;
std::vector<std::thread> workers;
int threadNumber;
// create 2 threads and pass a number
for(int i=0; i<2;++i)
{
// threadNumber = 0 for 1st thread
if(i==0)
{
threadNumber = i;
}
// threadNumber = 1 for 2nd thread
if(i==1)
{
threadNumber = i;
}
workers.push_back(std::thread([&obj,threadNumber]()
{
obj.myprint(threadNumber);
}));
}
// join all threads
std::for_each(workers.begin(), workers.end(),[](std::thread & th)
{
th.join();
});
return 0;
}
When you create your threads, you explicitly ask the compiler to provide the thread with access to the same instance of the variable threadNumber that the main function/thread is using.
[&threadNumber]
Again: this is an explicit share.
Indeed, your code suggests that you might want to better grasp the language before you experiment with threading, this code is very strange:
int threadNumber;
// create 2 threads and pass a number
for(int i=0; i<2;++i)
{
// threadNumber = 0 for 1st thread
if(i==0)
{
threadNumber = i;
}
// threadNumber = 1 for 2nd thread
if(i==1)
{
threadNumber = i;
}
It's unclear why anyone would write this instead of:
for (int i = 0; i < 2; ++i) {
workers.push_back(std::thread([&obj, i] () {
obj.myprint(threadNumber);
}));
}
Even this still has a number of design oddities - why are you passing obj by reference? It's an empty class with one static member, you could just as easily avoid the capture and write:
for (int i = 0; i < 2; ++i) {
workers.emplace_back([] (int threadNumber) {
ThreadSafePrint obj;
obj.myprint(threadNumber);
}, i); // pass `i` -> `threadNumber`
}

boost::variant vs. polymorphism, very different performance results with clang and gcc

I'm trying to figure out how much the execution time of boost::variant differ from a polymorphism approach. In my first test I got very different results on gcc 4.9.1 and clang+llvm 3.5.
You can find the code below. Here are my results:
clang+llvm
polymorphism: 2.16401
boost::variant: 3.83487
gcc:
polymorphism: 2.46161
boost::variant: 1.33326
I compiled both with -O3.
Is someone able to explain that?
code
#include <iostream>
#include <vector>
#include <algorithm>
#include <boost/variant.hpp>
#include <boost/variant/apply_visitor.hpp>
#include <ctime>
struct value_type {
value_type() {}
virtual ~value_type() {}
virtual void inc() = 0;
};
struct int_type : value_type {
int_type() : value_type() {}
virtual ~int_type() {}
void inc() { value += 1; }
private:
int value = 0;
};
struct float_type : value_type {
float_type() : value_type() {}
virtual ~float_type() {}
void inc() { value += 1; }
private:
float value = 0;
};
void dyn_test() {
std::vector<std::unique_ptr<value_type>> v;
for (int i = 0; i < 1024; i++) {
if (i % 2 == 0)
v.emplace_back(new int_type());
else
v.emplace_back(new float_type());
}
for (int i = 0; i < 900000; i++) {
std::for_each(v.begin(), v.end(), [](auto &item) { item->inc(); });
}
}
struct visitor : boost::static_visitor<> {
template <typename T> void operator()(T &item) { item += 1; }
};
using mytype = boost::variant<int, float>;
void static_test() {
std::vector<mytype> v;
for (int i = 0; i < 1024; i++) {
if (i % 2 == 0)
v.emplace_back(0);
else
v.emplace_back(0.f);
}
visitor vi;
for (int i = 0; i < 900000; i++) {
std::for_each(v.begin(), v.end(), boost::apply_visitor(vi));
}
}
template <typename F> double measure(F f) {
clock_t start = clock();
f();
clock_t end = clock();
float seconds = (float)(end - start) / CLOCKS_PER_SEC;
return seconds;
}
int main() {
std::cout << "polymorphism: " << measure([] { dyn_test(); }) << std::endl;
std::cout << "boost::variant: " << measure([] { static_test(); }) << std::endl;
return 0;
}
assembler
gcc
clang+llvm
Clang is known to miscompile some std::vector functions from various Standard libraries, due to some edge cases in their inliner. I don't know if those have been fixed by now but quite possibly not. Since unique_ptr is smaller and simpler than boost::variant it's more likely that it does not trigger these edge cases.
The code you post is practically "Why boost::variant is great". A dynamic allocation and random pointer index in addition to the regular indirections that both perform? That's a heavy hit (relatively).

Simple multithreading mutex example is incorrect

I expect to get numbers from 0 to 4 in random order, but instead, I have some unsynchronized mess
What i do wrong?
#include <iostream>
#include <windows.h>
#include <process.h>
using namespace std;
void addQuery(void *v );
HANDLE ghMutex;
int main()
{
HANDLE hs[5];
ghMutex = CreateMutex( NULL, FALSE, NULL);
for(int i=0; i<5; ++i)
{
hs[i] = (HANDLE)_beginthread(addQuery, 0, (void *)&i);
if (hs[i] == NULL)
{
printf("error\n"); return -1;
}
}
printf("WaitForMultipleObjects return: %d error: %d\n",
(DWORD)WaitForMultipleObjects(5, hs, TRUE, INFINITE), GetLastError());
return 0;
}
void addQuery(void *v )
{
int t = *((int*)v);
WaitForSingleObject(ghMutex, INFINITE);
cout << t << endl;
ReleaseMutex(ghMutex);
_endthread();
}
You have to read and write the shared variable inside the lock. You are reading it outside of the lock and thus rendering the lock irrelevant.
But even that's not enough since your shared variable is a loop variable that you are writing to without protection of the lock. A much better example would run like this:
#include <iostream>
#include <windows.h>
#include <process.h>
using namespace std;
void addQuery(void *v );
HANDLE ghMutex;
int counter = 0;
int main()
{
HANDLE hs[5];
ghMutex = CreateMutex( NULL, FALSE, NULL);
for(int i=0; i<5; ++i)
{
hs[i] = (HANDLE)_beginthread(addQuery, 0, NULL);
if (hs[i] == NULL)
{
printf("error\n"); return -1;
}
}
printf("WaitForMultipleObjects return: %d error: %d\n",
(DWORD)WaitForMultipleObjects(5, hs, TRUE, INFINITE), GetLastError());
return 0;
}
void addQuery(void *v)
{
WaitForSingleObject(ghMutex, INFINITE);
cout << counter << endl;
counter++;
ReleaseMutex(ghMutex);
_endthread();
}
If you can, use a critical section rather than a mutex because they are simpler to use and more efficient. But they have the same semantics in that they only protect code inside the locking block.
Note: Jerry has pointer out some other problems, but I've concentrated on the high level trheading and serialization concerns.
Your synchronization has some issues as you want to get numbers from 0 to 4 in random order.
The problem is that the variable i is write outside the lock and every time the addQuery method get called by the execution of a thread, it get the modified version of variable i. That why you may see 5 as the value at the output for all.
So, here is my fix for this scenario. Instead of pass the address of variable i in parameters of the function addQuery, you should pass it's value. Hope it helps:
#include <iostream>
#include <windows.h>
#include <process.h>
using namespace std;
void addQuery(void *v);
HANDLE ghMutex;
int main()
{
HANDLE hs[5];
ghMutex = CreateMutex(NULL, FALSE, NULL);
for (int i = 0; i<5; ++i)
{
hs[i] = (HANDLE)_beginthread(addQuery, 0, (void *)i);
if (hs[i] == NULL)
{
printf("error\n"); return -1;
}
}
printf("WaitForMultipleObjects return: %d error: %d\n",
(DWORD)WaitForMultipleObjects(5, hs, TRUE, INFINITE), GetLastError());
return 0;
}
void addQuery(void *v)
{
int t = (int)v;
WaitForSingleObject(ghMutex, INFINITE);
cout << t << endl;
ReleaseMutex(ghMutex);
_endthread();
}

Resources