How to sync "for" loop counter in multithread? - c++

How to sync "for" loop counter on multithread?
If these multi thread program
void Func(int n){
for(int i=0; i<n; i++){ //at the same time with other Func()
cout << i <<endl;
}
}
void main(){
std::thread t1(Func(2));
std::thread t2(Func(2));
t1.join();
t2.join();
}
When executing Func() in parallel , I want to sync "for" loop counter "i".
For example, the program has possibility to output the result
0
1
0
1
but I want to always get the result
0
0
1
1
Can I it?

If you use OpenMP to thread your loop you can use a #pragma omp barrier statement.
In C++11 you can use a condition_variable to block all threads until they reach the same spot.

One way to do it would be to use a few variables for the threads to coordinate things (in the following they are globals, just for simplicity).
mutex m;
condition_variable c;
static int index = 0;
static int count = 2;
The index variable says at which index are the threads, and the count variable says how many threads are at the index still.
Now you're loop becomes:
void Func(int n){
for(int i=0; i<n; i++){ //at the same time with other Func()
unique_lock<mutex> l(m);
c.wait(l, [i](){return index == i;});
cout << i <<endl;
if(--count == 0)
{
++index;
count = 2;
c.notify_one();
}
}
}
Here is the full code:
#include <thread>
#include <mutex>
#include <condition_variable>
#include <iostream>
using namespace std;
mutex m;
condition_variable c;
static int index = 0;
static int count = 2;
void Func(int n){
for(int i=0; i<n; i++){ //at the same time with other Func()
unique_lock<mutex> l(m);
c.wait(l, [i](){return index == i;});
cout << i <<endl;
if(--count == 0)
{
++index;
count = 2;
c.notify_one();
}
}
}
int main(){
std::thread t1(Func, 20);
std::thread t2(Func, 20);
t1.join();
t2.join();
}

You can use a std:atomic variable and pass it to all threads.
void Func(int n, int & i){
for (; i<n; i++){ //at the same time with other Func()
cout << i << endl;
}
}
void main(){
std::atomic<int> counter = 0;
std::thread t1(Func, 2, std::ref(counter));
std::thread t2(Func, 2, std::ref(counter));
t1.join();
t2.join();
}
Also you should note that the way you are crating your threads in your example are incorrect. Secondly if you are using cout in multiple threads each cout should be guarded with a std::mutex as cout is not thread safe.

Related

Threads not exiting?

I am trying to write a program to solve the producer consumer problem with threads in C++, and from what I can tell the program works fine until the very end when the threads are supposed to exit with the join() function. (The Product object is a simple data container).
#include <iostream>
#include <random>
#include <cstdlib>
#include <ctime>
#include <chrono>
#include <sstream>
#include <vector>
#include <stack>
#include <thread>
#include <mutex>
#include <atomic>
#include <condition_variable>
#include <Product.h>
using namespace std;
const int max_items = 100;
atomic<int> itemNum(0);
atomic<int> numProducersWorking(0);
stack<Product> items;
int maxBuffer;
float storeSales[10];
float monthSales[12];
float totalSales;
mutex xmutex;
condition_variable isNotFull;
condition_variable isNotEmpty;
int intRand(const int & min, const int & max) {
static thread_local mt19937 generator(time(0));
uniform_int_distribution<int> distribution(min,max);
return distribution(generator);
}
float floatRand(const float & min, const float & max) {
static thread_local mt19937 generator(time(0));
uniform_real_distribution<float> distribution(min,max);
return distribution(generator);
}
void produce(int pId)
{
unique_lock<mutex> lock(xmutex);
int day, month, year, id, regNum;
float saleAmnt;
Product item;
id = pId;
day = intRand(1, 30);
month = intRand(1, 12);
year = 20;
regNum = intRand(1, 6);
saleAmnt = floatRand(0.50, 999.99);
item = Product(day, month, year, id, regNum, saleAmnt);
isNotFull.wait(lock, [] { return items.size() != maxBuffer; });
if(itemNum < max_items)
{
items.push(item);
itemNum++;
}
isNotEmpty.notify_all();
}
void consume(int cId)
{
unique_lock<mutex> lock(xmutex);
Product item;
isNotEmpty.wait(lock, [] { return items.size() > 0; });
item = items.top();
items.pop();
storeSales[item.getStoreID()-1] += item.getSaleAmnt();
monthSales[item.getMonth()-1] += item.getSaleAmnt();
totalSales += item.getSaleAmnt();
isNotFull.notify_all();
}
void producer(int id)
{
++numProducersWorking;
while(itemNum < max_items)
{
produce(id);
this_thread::sleep_for(chrono::milliseconds(intRand(5, 40)));
}
--numProducersWorking;
}
void consumer(int id)
{
while(numProducersWorking != 0 || items.size() > 0 )
{
consume(id);
}
}
int main()
{
int p, c, b;
p = 5;
c = 5;
b = 5;
maxBuffer = b;
vector<thread> prodsCons;
auto start = chrono::high_resolution_clock::now();
//create producers
for(int i = 1; i <= p; i++)
{
prodsCons.push_back(thread(producer, i));
}
//create consumers
for(int i = 0; i < c; i++)
{
prodsCons.push_back(thread(consumer, i));
}
int x = 0;
//wait for consumers and producers to finish
for(auto& th : prodsCons)
{
th.join();
cout<<"thread "<<x<<" joined"<<endl;
x++;
}
auto stop = chrono::high_resolution_clock::now();
auto duration = chrono::duration_cast<chrono::microseconds>(stop - start);
cout<<"Store-wide total sales: "<<endl;
for(int x = 1; x <= p; x++)
{
cout<<" store "<<x<<" sales: $"<<storeSales[x-1]<<endl;
}
cout<<"Month-wise total sales: "<<endl;
for(int x = 1; x <= 12; x++)
{
cout<<" month "<<x<<" sales: $"<<monthSales[x-1]<<endl;
}
cout<<"Total sales: $"<<totalSales<<endl;
cout<<"Simulation time: "<<duration.count()<<" microseconds"<<endl;
}
The output looks like this:
thread 0 joined
thread 1 joined
thread 2 joined
thread 3 joined
thread 4 joined
indicating that 5 out of the 10 threads aren't exiting (most likely the consumers), and so the program never reaches the end. Is there a condition that isn't being fulfilled, or did I implement the mutexes incorrectly?
Once the consume thread reaches the condition_variable::wait call inside consume(), it will not return without some sort of signal.
I typically have a flag shutdown, which is protected by the same mutex as the queue, and my wait condition is going to be based on the shutdown flag and the size.
When its time for the consumers to stop, I acquire the mutex, and set the shutdown flag. Then, on exit from the wait, I will either exit immediately on shutdown, or only if the queue is also empty. The former is an immediate shutdown, while the latter is a shutdown once work is complete.
Also, all access to the items stack must be protected by the mutex. You've done that in some places, but not others.

Can't tell if Mutex Lock is kicking in or not?

I'm working on a college assignment and have been tasked with showing a basic mutex lock example. I've never worked with threads in any form, so I'm a total beginner working with POSIX threads in C++.
What I'm trying to get the program to do is create 1000 threads that increment a global integer by 1000.
#include <iostream>
#include <stdlib.h>
#include <pthread.h>
#include <sys/types.h>
#include <unistd.h>
#include <thread>
pthread_t threadArr[1000];
pthread_mutex_t lock;
// Global int to increment
int numberToInc = 0;
void* incByTwo(void*)
{
pthread_mutex_lock(&lock);
for(int j = 0; j < 1000; j++){
numberToInc += 1;
}
pthread_mutex_unlock(&lock);
return NULL;
}
int main()
{
//Creates 1000 threads with incByTwo func
for(int i = 0; i < 1000; i++){
pthread_create(&threadArr[i], NULL, incByTwo, NULL);
}
std::cout << "\n" << numberToInc << "\n";
return 0;
}
The following produces a series of different results, obviously because the threads are executing concurrently, right?
Now, I've gotten it to work correctly by inserting
for(int i = 0; i < 1000; i++){
pthread_join(threadArr[i], NULL);
}
After the thread creation loop, but then removing the mutex locks, it still works. I've been trying to piece out how pthread_join works but I'm a little lost. Any advice?
Sorted a way to show the mutex lock in action. So when I output the global var in the function, without mutex locks it has the potential to show the results out of order.
Running the number range with mutex locks, out looks like:
1000
2000
3000
... (etc)
10000
With mutex locks removed, the output can vary in the order.
E.g.
1000
2000
4000
6000
3000
5000
7000
8000
9000
10000
While the final result of the three threads is correct, the sequence is out of order. In the context of this program it doesn't really matter but I'd imagine if it's passing inconsistently sequenced values it messes things up?
pthread_t threadArr[10];
pthread_mutex_t lock;
int numberToInc = 0;
void* incByTwo(void*)
{
pthread_mutex_lock(&lock);
for(int j = 0; j < 1000; j++){
numberToInc += 1;
}
std::cout << numberToInc << "\n";
pthread_mutex_unlock(&lock);
return NULL;
}
int main()
{
if (pthread_mutex_init(&lock, NULL) != 0)
{
printf("\n mutex init failed\n");
return 1;
}
for(int i = 0; i < 10; i++){
pthread_create(&threadArr[i], NULL, incByTwo, NULL);
}
pthread_join(threadArr[0], NULL);
return 0;
}

Is there a race condition when one thread is constantly querying a variable from memory while another thread updates it?

I have the following code
#include <stdio.h>
#include <thread>
#include <mutex>
class A
{
public:
A(int n) : num_workers(n) {
counter_lock = new std::mutex();
threads = new std::thread[num_workers];
for (int i = 0; i < num_workers; i++) {
threads[i] = std::thread(&A::run, this);
}
}
~A() {
delete counter_lock;
}
void start() {
go = true;
counter = 0;
total = 1000000;
while (counter < total) {};
for (int i = 0; i < num_workers; i++) {
threads[i].join();
}
}
void run() {
printf("Spinning\n");
while(1) {
if (go) {
int i;
counter_lock->lock();
i = counter++;
counter_lock->unlock();
if (i >= total) break;
}
}
printf("Done\n");
}
private:
std::mutex* counter_lock;
std::thread* threads;
int num_workers;
int counter;
int total;
bool active;
bool go;
};
int main() {
A a = A(10);
a.start();
}
In the constructor of A I create a thread pool of num_workers. They are all executing a function A::run which simply waits until it gets a signal to go and then starts incrementing the counter. The function start is meant to be synchronous with whomever called it, so in this case it should be synchronous with main. Therefore, it just idles until the counter reaches total after issuing the signal to go to all the worker threads.
The code works as expected. The counter ends up at 10000010 which makes sense because each of the 10 threads have incremented the counter once before quitting.
Is there a race condition here that I'm not noticing? Is the fact that I'm reading counter in the while(counter < total) {} loop without a lock causing any problems?
Thanks for any advice.
EDIT: I replaced the while (counter < total) {} loop with the following, perhaps more thread safe, implementation. But, very rarely, it still ends up looping forever since the value of counter hasn't updated.
while (1) {
int c;
counter_lock->lock();
c = counter;
counter_lock->unlock();
if (c >= total) break;
};

Mutex for two threads in C++

I've created two threads that use a variable declared in main via pthread_create's last argument. I want thread2 to use modify the value of that variable after thread1 is done with a set of particular instructions. I know how we can use mutex in one thread but how about two or more threads?
Refer to the following code:
#include<iostream>
#include<unistd.h>
#include<stdlib.h>
#include<pthread.h>
#define NUM 6
using namespace std;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
void *even(void *arg)
{
int sum = 0;
int count = 0;
for (int i = 1; count < NUM/2; i++)
{
if( !(i % 2) )
{
count++;
sum += i;
}
}
cout << "In Even Thread: " << sum << endl;
pthread_mutex_lock(&mutex);
*((int*)arg) = sum;
pthread_mutex_unlock(&mutex);
pthread_cond_signal(&cond);
}
void *odd(void *arg)
{
int sum = 0;
int count = 0;
for (int i = 1; count < NUM/2; i++)
{
if( i % 2 )
{
count++;
sum += i;
}
}
cout << "In Odd Thread: " << sum << endl;
pthread_cond_wait(&cond, &mutex);
*((int*)arg) = *((int*)arg) + sum;
}
int main()
{
int mainSum = 0;
pthread_t tidO, tidE;
pthread_create(&tidO, NULL, odd, (void *)&mainSum);
pthread_create(&tidE, NULL, even, (void *)&mainSum);
pthread_join(tidO, NULL);
pthread_join(tidE, NULL);
cout << "Sum of first " << NUM << " Natural Numbers: " << mainSum << endl;
return 0;
}
You should lock mutex before accessing the variable and unlock after you finish you finish you job with the variable. Use lock_guard to keep mutex locked and use brackets for lock_guard lifetime. http://www.cplusplus.com/reference/mutex/lock_guard/
std::mutex mtx; //global mutex
int v; //global variable;
int k;
...
//repeat this code in each thread to access the variable
{
std::lock_guard<std::mutex> lck (mtx);
//access the variable;
k = v; //read global variable or
v = k; //write
}
Your use case needs a condition variable combined with a mutex.
http://en.cppreference.com/w/cpp/thread/condition_variable
You should create mutex in same place as shared variable. In your case it is main function.
Then you need to share this mutex in all threads which are accessing shared variable.
You can share this mutex over global variable or better in same attribute as shared variable. But you will have to define structure where you place variable and mutex together.
Update
You should lock mutex pthread_mutex_lock(&mutex); before pthread_cond_wait(&cond, &mutex);
The pthread_cond_signal() and pthread_cond_broadcast() functions have no effect if there are no threads currently blocked on cond.

Why the runtime it hasn't halved on using the multithreading in C++?

Now, the code takes 866678 clock ticks when the code is run in multithread and when I comment the for loops in the threads(each FOR loop runs 10000 times) and just run the whole FOR loop (20000 times). The run time is same for both with and without threads. But ideally it should have been half right?
// thread example
#include <iostream> // std::cout
#include <thread> // std::thread
#include <time.h>
#include<cmath>
#include<unistd.h>
int K = 20000;
long int a[20000];
void makeArray(){
for(int i=0;i<K;i++){
a[i] = i;
}
}
void foo()
{
// do stuff...
std::cout << "FOOOO Running...\n";
for(int i=K/2;i<K;i++){
// a[i] = a[i]*a[i]*10;
// a[i] = exp(2/5);
int j = i*i;
usleep(2000);
}
}
void bar(int x)
{
// do stuff...
std::cout << "BARRRR Running...\n";
for(int i=0;i<K/2;i++){
//a[i] = a[i]*a[i];
int j = i*i;
usleep(2000);
}
}
void show(){
std::cout<<"The array is:"<<"\n";
for(int i=0; i <K;i++){
std::cout<<a[i]<<"\n";
}
}
int main()
{
clock_t t1,t2;
t1 = clock();
makeArray();
// show();
std::thread first (foo); // spawn new thread that calls foo()
std::thread second (bar,0); // spawn new thread that calls bar(0)
//show();
std::cout << "main, foo and bar now execute concurrently...\n";
// synchronize threads:
first.join(); // pauses until first finishes
second.join(); // pauses until second finishes
//show();
// for(int i=0;i<K;i++){
// int j = i*i;
// //a[i] = a[i]*a[i];
// usleep(2000);
// }
std::cout << "foo and bar completed.\n";
//show();
t2 = clock();
std::cout<<"Runtime:"<< (float)t2-(float)t1<<"\n";
return 0;
}
The problem is in your use of clock(). This function actually returns the total amount of CPU run time consumed by your program across all cores / CPUs.
What you are actually interested in is the wall clock time that it took for your program to complete.
Replace clock() with time(), gettimeofday() or something similar to get what you want.
EDIT - Here's the C++ way to do timers the way you want: http://www.cplusplus.com/reference/chrono/high_resolution_clock/now/