Synchronisation before pthread_cond_broadcast - c++

I want to send a broadcast signal from the main thread to all the other threads waiting for a condition. It seems to me that the broadcast signal comes to early to the threads.
#include <iostream>
#include <pthread.h>
#define NUM 4
#define SIZE 256
using namespace std;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
pthread_barrier_t barrier;
class cache{
int lv1;
public:
int write(int i){
lv1=i;
pthread_cond_broadcast(&cond);
}
};
cache c[NUM];
void *thread(void *arg){
int i = (int)arg;
for(;;){
pthread_mutex_lock(&mutex);
pthread_cond_wait(&cond,&mutex);
cout << "Thread: "<< i << endl;
//do some work
pthread_mutex_unlock(&mutex);
}
}
int main()
{
pthread_t tid[NUM];
pthread_barrier_init(&barrier,NULL,NUM+1);
for(int i=0;i<NUM;i++){
pthread_create(&tid[i],NULL,thread,(void*)i);
}
//Sleep(2);
c[0].write(55); //broadcast signal
//Sleep(2);
c[1].write(44); //broadcast signal
for(int i=0;i<NUM;i++){
pthread_join(tid[i],NULL);
}
cout << "Hello world!" << endl;
return 0;
}
If I insert Sleep(2) in the main function, it works, but I do not want to wait a time but a synchronisation before calling pthread_broadcast.
I thought of a barrier, but pthread_cond_wait is blocking, right?

You need to read up on how condition variables are used. You also handled the integer arguments to your threads erroneously. Here is a fixed version, hopefully similar to what you wanted:
#include <iostream>
#include <pthread.h>
#include <unistd.h>
#define NUM 4
#define SIZE 256
using namespace std;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
pthread_barrier_t barrier;
class cache{
int lv1;
public:
int write(int i) { lv1=i; }
const int val() { return lv1; }
};
cache c[NUM];
void *thread(void *arg)
{
int i = *(int*)arg;
for(;;) {
pthread_mutex_lock(&mutex);
// Check predicate, do not go to sleep if predicate is fulfilled
if (c[0].val() > 0 && c[1].val() > 0) {
cout << "Thread " << i << " leaving...\n";
pthread_mutex_unlock(&mutex);
return 0;
}
pthread_cond_wait(&cond, &mutex);
cout << "Thread wakeup: "<< i << endl;
// do some work
pthread_mutex_unlock(&mutex);
}
}
int main()
{
pthread_t tid[NUM];
int arg[NUM];
for(int i=0; i<NUM; i++) {
arg[i] = i; // make a copy of i used by only one thread
pthread_create(&tid[i], NULL, thread,(void*)&arg[i]);
}
pthread_mutex_lock(&mutex);
c[0].write(55);
c[1].write(44);
pthread_mutex_unlock(&mutex);
pthread_cond_broadcast(&cond); // Signal all threads that predicate is fulfilled
for(int i=0; i<NUM; i++) {
pthread_join(tid[i],NULL);
cout << "Joined " << i << '\n';
}
cout << "Hello world!" << endl;
return 0;
}

Sequence how I think it is
This is how it is right now I think, I still need a way to synchronise, before I send the broadcast signal.
In that picture, the first pthread_broadcast comes too early.

Related

Why my thread is not running at all? (Cpp multithreading)

I am new to threading, and i am trying to write a function that keep outputing an variable while i should be able to change that variable at runtime, and the output should change to my input once I input a new value in. By the following program is not running as i expected, whats wrong here? is there anything i can reference to so i can build this funciton out?
int a;
void* ptr;
void* Input(void* arg){
while(true){
std::cin >> a;
std::cout << std::endl;
}
return ptr;
}
void* Output(void *arg){
while(true){
std::cout << a << std::endl;
}
return ptr;
}
int main(){
pthread_t GetInput;
pthread_create(&GetInput,NULL,Input,NULL);
pthread_t GetOutput;
pthread_create(&GetOutput,NULL,Output,NULL);
}
Your main thread is not waiting for your child thread and exited when main() returned. To make your main thread to wait for children finish their jobs, you should call pthread_join() for them.
int main(){
pthread_t GetInput;
pthread_create(&GetInput,NULL,Input,NULL);
pthread_t GetOutput;
pthread_create(&GetOutput,NULL,Output,NULL);
pthread_join(GetInput, NULL);
pthread_join(GetOutput, NULL);
return 0;
}
Here's another alternative using std::async() for your code.
#include <chrono>
#include <future>
#include <iostream>
#include <mutex>
int a;
std::mutex mtx_;
void Input(void* arg) {
while (true) {
int tmp_a;
std::cin >> tmp_a;
{
std::lock_guard<std::mutex> lock(mtx_);
a = tmp_a;
}
std::cout << std::endl;
}
}
void Output(void* arg) {
while (true) {
{
std::lock_guard<std::mutex> lock(mtx_);
std::cout << a << std::endl;
}
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
int main() {
auto ft_in = std::async(std::launch::async, Input, &a);
auto ft_out = std::async(std::launch::async, Output, &a);
ft_in.wait();
ft_out.wait();
return 0;
}
Well,I don't know how to use pthread.
And it seems Mr.john-park or Ms.john-park already gave a answer.
But I think use thread is a better choice.
To use it,we should:
#include<thread>
After that,if u want to start a new thread,and "connect" it with a function(In fact,we usually do)
There is a class named thread.
First,we should
thread *thread name*(*function name*);
WARNING:function nameshould be without "(" and ")"
May because here should be a pointer.
Then,to the question.
Suppose we wrote:
thread GetInput(Input);
thread GetOutput(Output);
When u want to stop GetOutput some time and run GetInput,
just
GetInput.join()
Here's a not so good example:
#include <iostream>
#include <thread>
using namespace std;
void f1()
{
while (true)
{
cout << "THREAD 1!" << endl;
}
}
void f2()
{
for (int i = 0; i < 10; i++)
cout << "THREAD 2!" << endl;
thread t1(f1);
t1.join();
for (int i = 0; i < 10; i++)
cout << "THREAD 2!" << endl;
}
int main()
{
thread t2(f2);
return 0;
}
First,we started t2.
Then t2 started t1.
Now we can know why we use join().
If we don't join(),
It'll be hard for us to read the output because it'll close the cmd window quickly.
But we can know,
after t2 end,
return 0;
ran.
But if we used join()
Here's the output:
THREAD 2!
THREAD 2!
THREAD 2!
...(THREAD 2!*10)
THREAD 1!
THREAD 1!
...(Always THREAD 1!)

Sandard way of implementing c++ multi-threading for collecting data streams and processing

I'm new to c++ development. I'm trying to run infinite functions that are independent of each other.
Problem statement is smiliar to this:
The way I'm trying to implement this is
#include <iostream>
#include <cstdlib>
#include <pthread.h>
#include <unistd.h>
#include <mutex>
int g_i = 0;
std::mutex g_i_mutex; // protects g_i
// increment g_i by 1
void increment_itr()
{
const std::lock_guard<std::mutex> lock(g_i_mutex);
g_i += 1;
}
void *fun(void *s)
{
std::string str;
str = (char *)s;
std::cout << str << " start\n";
while (1)
{
std::cout << str << " " << g_i << "\n";
if(g_i > 1000) break;
increment_itr();
}
pthread_exit(NULL);
std::cout << str << " end\n";
}
void *checker(void *s) {
while (1) {
if(g_i > 1000) {
std::cout<<"**********************\n";
std::cout << "checker: g_i == 100\n";
std::cout<<"**********************\n";
pthread_exit(NULL);
}
}
}
int main()
{
int itr = 0;
pthread_t threads[3];
pthread_attr_t attr;
void *status;
// Initialize and set thread joinable
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
int rc1 = pthread_create(&threads[0], &attr, fun, (void *)&"foo");
int rc2 = pthread_create(&threads[1], &attr, fun, (void *)&"bar");
int rc3 = pthread_create(&threads[2], &attr, checker, (void *)&"checker");
if (rc1 || rc2 || rc3)
{
std::cout << "Error:unable to create thread," << rc1 << rc2 << rc3 << std::endl;
exit(-1);
}
pthread_attr_destroy(&attr);
std::cout << "main func continues\n";
for (int i = 0; i < 3; i++)
{
rc1 = pthread_join(threads[i], &status);
if (rc1)
{
std::cout << "Error:unable to join," << rc1 << std::endl;
exit(-1);
}
std::cout << "Main: completed thread id :" << i;
std::cout << " exiting with status :" << status << std::endl;
}
std::cout << "main end\n";
return 0;
}
This works, but I want to know if this implementation is a standard approach to do this or this can be done in any better way?
You correctly take a lock inside increment_itr, but your fun function is accessing g_i without acquiring the lock.
Change this:
void increment_itr()
{
const std::lock_guard<std::mutex> lock(g_i_mutex);
g_i += 1;
}
To this
int increment_itr()
{
std::lock_guard<std::mutex> lock(g_i_mutex); // the const wasn't actually needed
g_i = g_i + 1;
return g_i; // return the updated value of g_i
}
This is not thread safe:
if(g_i > 1000) break; // access g_i without acquiring the lock
increment_itr();
This this is better:
if (increment_itr() > 1000) {
break;
}
Similar fix is needed in checker:
void *checker(void *s) {
while (1) {
int i;
{
std::lock_guard<std::mutex> lock(g_i_mutex);
i = g_i;
}
if(i > 1000) {
std::cout<<"**********************\n";
std::cout << "checker: g_i == 100\n";
std::cout<<"**********************\n";
break;
}
return NULL;
}
As to your design question. Here's the fundamental issue.
You're proposing a dedicated thread that continuously takes a lock and would does some sort checking on a data structure. And if a certain condition is met, it would do some additional processing such as writing to a database. The thread spinning in an infinite loop would be wasteful if nothing in the data structure (the two maps) has changed. Instead, you only want your integrity check to run when something changes. You can use a condition variable to have the checker thread pause until something actually changes.
Here's a better design.
uint64_t g_data_version = 0;
std::conditional_variable g_cv;
void *fun(void *s)
{
while (true) {
<< wait for data from the source >>
{
std::lock_guard<std::mutex> lock(g_i_mutex);
// update the data in the map while under a lock
// e.g. g_n++;
//
// increment the data version to signal a new revision has been made
g_data_version += 1;
}
// notify the checker thread that something has changed
g_cv.notify_all();
}
}
Then your checker function only wakes up when it fun signals it to say something has changed.
void *checker(void *s) {
while (1) {
// lock the mutex
std::unique_lock<std::mutex> lock(g_i_mutex);
// do the data comparison check here
// now wait for the data version to change
uint64_t version = g_data_version;
while (version != g_data_version) { // check for spurious wake up
cv.wait(lock); // this atomically unlocks the mutex and waits for a notify() call on another thread to happen
}
}
}

How to change this notify_one so that it chooses a random thread?

Thanks in advance for any help.
Trying to make a program that would create 6 threads, then each 2 seconds randomly choose one and make it print its number. I am obviously doing something wrong, because it just keeps printing 0-1-2-3-4-5 endlessly. The code is below.
Main question is, what should i do to make random threads unlock?
#include <thread>
#include <memory>
#include <chrono>
#include <condition_variable>
std::condition_variable* cv = new std::condition_variable();
std::mutex cv_m;
void threadFunc(std::shared_ptr<bool> flag2, int id)
{
while (true)
{
std::unique_lock<std::mutex> lock(cv_m);
cv->wait(lock);
if (true)
if (*flag2) std::cout << "Thread" << " " << id << std::endl;
}
}
int main() {
std::shared_ptr<bool> f2 = std::make_shared<bool>(false);
std::thread threads[6];
for (int i = 0; i < 6; i++)
threads[i] = std::thread(threadFunc, f2, i);
*f2 = true;
while (true)
{
cv->notify_one();
std::this_thread::sleep_for(std::chrono::seconds(2));
}
return 0;
}
You can use a condition variable for each thread, it should be false for each thread at the beginning, then change a random condition variable to true and notify all, this will make a random thread to wake up (the thread that owns that condition variable)
here is the full solution
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <unistd.h>
#include "UserInterruptHandler.h"
using namespace std;
UserInterruptHandler h;
condition_variable conditionalVariable;
mutex mtx;
bool flag = true;
void myMethod(int id, bool *canWork) {
unique_lock<mutex> ul(mtx);
while (flag) {
conditionalVariable.wait(ul,[=]{return *canWork;});
if(!flag)
break;
cout << "thread " << id << endl;
}
cout << "thread " << id << " exits.." << endl;
}
int main() {
cout << "input thread count" << endl;
int n;
cin >> n;
thread myThreads[n];
bool *canWork = new bool[n];
for (int i = 0; i < n; i++) {
canWork[i] = false;
myThreads[i] = thread(myMethod, i + 1, &canWork[i]);
}
while (!h.checkInterruption()) {
int i = rand() % n;
canWork[i] = true;
conditionalVariable.notify_all();
canWork[i] = false;
usleep(1000);
}
flag = false;
int i = 0;
for (thread &th:myThreads) {
canWork[i++] = true;
conditionalVariable.notify_all();
if (th.joinable())
th.join();
}
}
notice that here I am using header UserInterruptHandler.h to handle CTR+C event to end all threads gracefully

Why this conditon variable is not working?

I was trying to understand the condition_variable available in C++ standard. So in the below test code I have written, I expect the func1 to be woken up after printing 50 numbers in main thread but here it prints all numbers only from main thread?
Could you please help me here to understand condition_variable better to indicate a certain thread to wake up
I have tried to understand condition variable using below code:
#include <stdio.h>
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
using namespace std;
std::mutex mu;
std::condition_variable multiple;
bool isLoaded = false;
void func1()
{
std::unique_lock<std::mutex> unLock(mu);
multiple.wait(unLock, []() {return isLoaded; });
for (int i = 0; i < 100; i++)
{
cout << "This is from thread; " << i << endl;
}
}
int main()
{
std::thread t1(func1);
std::lock_guard<std::mutex> gaurd(mu);
cout << std::thread::hardware_concurrency()<< endl;
for (int i = 0; i < 100; i++)
{
if (i == 50)
{
isLoaded = true;
multiple.notify_one();
std::this_thread::sleep_for(std::chrono::seconds(4));
}
cout << "This is from main; " << i << endl;
}
t1.join();
getchar();
return 0;
}
You never release mu in main thread. Try something like this:
int main()
{
std::thread t1(func1);
cout << std::thread::hardware_concurrency()<< endl;
for (int i = 0; i < 100; i++)
{
if (i == 50)
{
{
std::lock_guard<std::mutex> gaurd(mu);
isLoaded = true;
}
multiple.notify_one();
std::this_thread::sleep_for(std::chrono::seconds(4));
}
cout << "This is from main; " << i << endl;
}
t1.join();
getchar();
return 0;
}
In general you need to keep your locks for absolute minimum of time you can.
You are taking mutex mu at start of your program and never let it go, so any other code under this mutex will never be executed.
Instead you should only hold it when you changing shared variables, something like:
{
std::lock_guard<std::mutex> gaurd(mu);
isLoaded = true;
multiple.notify_one();
}

Barrier Synchronization between 2 process using mutex

I need to implement barrier synchronization between 2 threads using mutex (only). Barrier synchronization is that 2 threads will wait for each other to meet at predefined step before proceeding.
I am able to do it using seamaphore but how can I achieve this only using mutex. I was given a hint that I need 2 mutex not 1 to do this.
Using Seamaphore:
#include <pthread.h>
#include <semaphore.h>
using namespace std;
sem_t s1;
sem_t s2;
void* fun1(void* i)
{
cout << "fun1 stage 1" << endl;
cout << "fun1 stage 2" << endl;
cout << "fun1 stage 3" << endl;
sem_post (&s1);
sem_wait (&s2);
cout << "fun1 stage 4" << endl;
}
void* fun2(void* i)
{
cout << "fun2 stage 1" << endl;
cout << "fun2 stage 2" << endl;
// sleep(5);
sem_post (&s2);
sem_wait (&s1);
cout << "fun2 stage 3" << endl;
}
main()
{
sem_init(&s1, 0, 0);
sem_init(&s2, 0, 0);
int value;
sem_getvalue(&s2, &value);
cout << "s2 = " << value << endl;
pthread_t iThreadId;
cout << pthread_create(&iThreadId, NULL, &fun2, NULL) << endl;
// cout << pthread_create(&iThreadId, NULL, &fun2, NULL) << endl;
pthread_create(&iThreadId, NULL, &fun1, NULL);
sleep(10);
}
Compile the above code as "g++ barrier.cc -lpthread"
How about NO MUTEXES and no locks? Using ATOMIC OPERATIONS only:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <signal.h>
static sigset_t _fSigSet;
static volatile int _cMax=20, _cWait = 0;
static pthread_t _aThread[1000];
void * thread(void *idIn)
{
int nSig, iThread, cWait, id = (int)idIn;
printf("Start %d\n", id, cWait, _cMax);
// do some fake weork
nanosleep(&(struct timespec){0, 500000000}, NULL);
// barrier
cWait = __sync_add_and_fetch(&_cWait, 1);
printf("Middle %d, %d/%d Waiting\n", id, cWait, _cMax);
if (cWait < _cMax)
{
// if we are not the last thread, sleep on signal
sigwait(&_fSigSet, &nSig); // sleepytime
}
else
{
// if we are the last thread, don't sleep and wake everyone else up
for (iThread = 0; iThread < _cMax; ++iThread)
if (iThread != id)
pthread_kill(_aThread[iThread], SIGUSR1);
}
// watch em wake up
cWait = __sync_add_and_fetch(&_cWait, -1);
printf("End %d, %d/%d Active\n", id, cWait, _cMax);
return 0;
}
int main(int argc, char** argv)
{
pthread_attr_t attr;
int i, err;
sigemptyset(&_fSigSet);
sigaddset(&_fSigSet, SIGUSR1);
sigaddset(&_fSigSet, SIGSEGV);
printf("Start\n");
pthread_attr_init(&attr);
if ((err = pthread_attr_setstacksize(&attr, 16384)) != 0)
{
printf("pthread_attr_setstacksize failed: err: %d %s\n", err, strerror(err));
exit(0);
}
for (i = 0; i < _cMax; i++)
{
if ((err = pthread_create(&_aThread[i], &attr, thread, (void*)i)) != 0)
{
printf("pthread_create failed on thread %d, error code: %d %s\n", i, err, strerror(err));
exit(0);
}
}
for (i = 0; i < _cMax; ++i)
pthread_join(_aThread[i], NULL);
printf("\nDone.\n");
return 0;
}
I am not sure that you need two mutexes, with one mutex and a condition variable and an extra flag might be enough. The idea is that you enter the critical section by acquiring the mutex, then you check whether you are the first thread to come, if so, you wait on the condition. If you are the second thread coming then you wake up the waiting thread and both leave.