Barrier Synchronization between 2 process using mutex - c++

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.

Related

Interrupt and, if necessary, terminate a program at regular intervals in c++

I need your help. Program A executes program B with fork(). Every 5 seconds the process belonging to program B is interrupted. If the user enters any key within a certain time, the process is continued and interrupted again after the same time interval. If no key is entered, both program A and program B are terminated prematurely. I have tried the following code, but it does not work. Any suggestions/tips that will help me?
#include <iostream>
#include <chrono>
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>
using namespace std;
using namespace chrono;
int pid;
void signal_handler(int signum) {
cout << "Programm B is interrupted. Please enter any key within 5 or the programm will be terminated" << endl;
kill(pid,SIGSTOP);
alarm(5);
pause();
alarm(5);
}
int main(int argc, char* argv[]) {
//Usage
if(string(argv[1]) == "h" || string(argv[1]) == "help"){
cout << "usage" << endl;
return 0;
}
signal(SIGALRM, signal_handler);
pid = fork();
if (pid == 0) {
cout << "Name of programm B: " << argv[1] << endl;
cout << "PID of programm B: " << getpid() << endl;
execvp(argv[1], &argv[1]);
} else if (pid > 0) {
cout << "PID of programm A: " << getpid() << endl;
high_resolution_clock::time_point t1 = high_resolution_clock::now();
waitpid(pid, nullptr, 0);
high_resolution_clock::time_point t2 = high_resolution_clock::now();
auto duration = duration_cast<milliseconds>(t2 - t1).count();
cout << "Computing time: " << duration << "ms" << endl;
} else {
cerr << "error << endl;
return 1;
}
return 0;
}
Any help or sulution. I am a beginner in c++ btw.
Signals can get tricky and there are lots of issues with your approach.
You should:
kick off the timer (alarm(5)) in main
do the sighandler registration and timer kick-off after you've spawned the child (or you somewhat risk running the signal handler in the child in between fork and execvp)
use sigaction rather than signal to register the signal, as the former has clear portable semantics unlike the latter
loop on EINTR around waitpid (as signal interruptions will cause waitpid to fail with EINTR)
As for the handler, it'll need to
use only async-signal-safe functions
register another alarm() around read
unblock SIGALRM for the alarm around read but not before you somehow mark yourself as being in your SIGALRM signal handler already so the potential recursive entry of the handler can do a different thing (kill the child and exit)
(For the last point, you could do without signal-unblocking if you register the handler with .sa_flags = SA_NODEFER, but that has the downside of opening up your application to stack-overflow caused by many externally sent (via kill) SIGALRMs. If you wanted to handle externally sent SIGALRMs precisely, you could register the handler with .sa_flags=SA_SIGINFO and use info->si_code to differentiate between user-sends and alarm-sends of SIGALRM, presumably aborting on externally-sent ones)
It could look something like this (based on your code):
#include <iostream>
#include <chrono>
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>
#include <string.h>
//AS-safe raw io helper functions
ssize_t /* Write "n" bytes to a descriptor */
writen(int fd, const char *ptr, size_t n)
{
size_t nleft;
ssize_t nwritten;
nleft = n;
while (nleft > 0) {
if ((nwritten = write(fd, ptr, nleft)) < 0) {
if (nleft == n)
return(-1); /* error, return -1 */
else
break; /* error, return amount written so far */
} else if (nwritten == 0) {
break;
}
nleft -= nwritten;
ptr += nwritten;
}
return(n - nleft); /* return >= 0 */
}
ssize_t writes(int fd, char const *str0) { return writen(fd,str0,strlen(str0)); }
ssize_t writes2(char const *str0) { return writes(2,str0); }
//AS-safe sigprockmask helpers (they're in libc too, but not specified as AS-safe)
int sigrelse(int sig){
sigset_t set; sigemptyset(&set); sigaddset(&set,sig);
return sigprocmask(SIG_UNBLOCK,&set,0);
}
int sighold(int sig){
sigset_t set; sigemptyset(&set); sigaddset(&set,sig);
return sigprocmask(SIG_BLOCK,&set,0);
}
#define INTERRUPT_TIME 5
using namespace std;
using namespace chrono;
int pid;
volatile sig_atomic_t recursing_handler_eh; //to differentiate recursive executions of signal_handler
void signal_handler(int signum) {
char ch;
if(!recursing_handler_eh){
kill(pid,SIGSTOP);
writes2("Programm B is interrupted. Please type enter within 5 seconds or the programm will be terminated\n");
alarm(5);
recursing_handler_eh = 1;
sigrelse(SIGALRM);
if (1!=read(0,&ch,1)) signal_handler(signum);
alarm(0);
sighold(SIGALRM);
writes2("Continuing");
kill(pid,SIGCONT);
recursing_handler_eh=0;
alarm(INTERRUPT_TIME);
return;
}
kill(pid,SIGTERM);
_exit(1);
}
int main(int argc, char* argv[]) {
//Usage
if(string(argv[1]) == "h" || string(argv[1]) == "help"){
cout << "usage" << endl;
return 0;
}
pid = fork();
if (pid == 0) {
cout << "Name of programm B: " << argv[1] << endl;
cout << "PID of programm B: " << getpid() << endl;
execvp(argv[1], &argv[1]);
} else if (pid < 0) { cerr << "error" <<endl; return 1; }
struct sigaction sa; sa.sa_handler = signal_handler; sigemptyset(&sa.sa_mask); sa.sa_flags=0; sigaction(SIGALRM, &sa,0);
//signal(SIGALRM, signal_handler);
alarm(INTERRUPT_TIME);
cout << "PID of programm A: " << getpid() << endl;
high_resolution_clock::time_point t1 = high_resolution_clock::now();
int r;
do r = waitpid(pid, nullptr, 0); while(r==-1 && errno==EINTR);
high_resolution_clock::time_point t2 = high_resolution_clock::now();
auto duration = duration_cast<milliseconds>(t2 - t1).count();
cout << "Computing time: " << duration << "ms" << endl;
return 0;
}
Not that the above will wait only for an enter key. To wait for any key, you'll need to put your terminal in raw/cbreak mode and restore the previous settings on exit (ideally on signal deaths too).

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
}
}
}

Creating 3 children processes and exiting them after a specified number of seconds

image for what output is supposed to look like:My problem is that I need to write a program that will accept the names of 3 processes as command-line arguments. Each of these processes will run for as many seconds as:(PID%10)*3+5 and terminate. After those 3 children terminated, the parent process
will reschedule each child. When all children have been rescheduled 3 times, the parent will terminate. I have used fork to create the three children but am struggling with getting them to exit with that specific criteria?
using namespace std;
int main(){
int i;
int pid;
for(i=0;i<3;i++) // loop will run n times (n=3)
{
if(fork() == 0)
{
pid = getpid();
cout << "Process p" << i+1 << " pid:" << pid << " Started..." << endl;
exit(0);
}
}
for(int i=0;i<5;i++) // loop will run n times (n=3)
wait(NULL);
}
You can use sigtimedwait to wait for SIGCHLD or timeout.
Working example:
#include <cstdio>
#include <cstdlib>
#include <signal.h>
#include <unistd.h>
template<class... Args>
void start_child(unsigned max_runtime_sec, Args... args) {
// Block SIGCHLD.
sigset_t set;
sigemptyset(&set);
sigaddset(&set, SIGCHLD);
sigprocmask(SIG_BLOCK, &set, nullptr);
// Enable SIGCHLD.
signal(SIGCHLD, [](int){});
pid_t child_pid = fork();
switch(child_pid) {
case -1:
std::abort();
case 0: {
// Child process.
execl(args..., nullptr);
abort(); // never get here.
}
default: {
// paren process.
timespec timeout = {};
timeout.tv_sec = max_runtime_sec;
siginfo_t info = {};
int rc = sigtimedwait(&set, nullptr, &timeout);
if(SIGCHLD == rc) {
std::printf("child %u terminated in time with return code %d.\n", static_cast<unsigned>(child_pid), info.si_status);
}
else {
kill(child_pid, SIGTERM);
sigwaitinfo(&set, &info);
std::printf("child %u terminated on timeout with return code %d.\n", static_cast<unsigned>(child_pid), info.si_status);
}
}
}
}
int main() {
start_child(2, "/bin/sleep", "/bin/sleep", "10");
start_child(2, "/bin/sleep", "/bin/sleep", "1");
}
Output:
child 31548 terminated on timeout with return code 15.
child 31549 terminated in time with return code 0.
With these changes your program produces the desired output:
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <iostream>
using namespace std;
int main()
{
for (int round = 0; ++round <= 4; )
{
int i;
cout << "*** ROUND: " << round << " ***\n";
for (i=0; i<3; i++) // loop will run n times (n=3)
{
if (fork() == 0)
{
int pid = getpid();
cout << "Process p" << i+1 << " pid:" << pid << " started...\n";
unsigned int seconds = pid%10*3+5;
cout << "Process " << pid << " exiting after "
<< seconds-sleep(seconds) << " seconds\n";
exit(0);
}
}
while (i--) // loop will run n times (n=3)
{
int status;
cout << "Process " << wait(&status);
cout << " exited with status: " << status << endl;
}
}
}
As Serge suggested, we're using sleep() for every child before exiting it. it will pause the process for a number of seconds.
To get the actual status information, we call wait(&status) instead of wait(NULL).
We're doing this all for the first scheduling round plus the desired 3 times of rescheduling.

Synchronisation before pthread_cond_broadcast

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.

Implementing a Semaphore

I have the following code below. I want only half of the threads to enter the threadedfunction at a time. How do I create a Semaphore to block the other processes? And how would I go about unblocking the previously blocked processes whenever the threads have finished using the function?
#include <iostream>
#include <unistd.h>
#include <sys/wait.h>
#include <pthread.h>
using namespace std;
#define NUM_THREADS 4
long int sharedcount;
pthread_mutex_t count_mutex;
//Function that will be run by multiple threads
//Needs to return a void pointer and if it takes arguments
//it needs to be a void pointer
void *ThreadedFunction(void *threadid)
{
int success;
long id = (long)threadid;
//Lock mutex preventing the other threads from ru nning
success = pthread_mutex_lock( &count_mutex );
cout << "Thread " << id << " beginning.\n";
for(int i = 0; i < 100000000; i++)
sharedcount++;
cout << "Thread " << id << " exiting.\n";
cout << sharedcount << endl;
//Unlock the mutex after the thread has finished running
pthread_mutex_unlock( &count_mutex );
//Kill the thread
pthread_exit(NULL);
}
int main ()
{
//Initialize mutex
pthread_mutex_init(&count_mutex, NULL);
//Create an array of threads
pthread_t threads[NUM_THREADS];
int rc;
int i;
sharedcount = 0;
for( i=0; i < NUM_THREADS; i++ )
{
cout << "main() : creating thread, " << i << endl;
//Create thread by storing it in a location in the array. Call the
//function for the threads to run inside. And pass the argument (if any).
//If no arguments pass NULL
rc = pthread_create(&threads[i], NULL, ThreadedFunction, (void *)i);
if (rc)
{
cout << "Error:unable to create thread," << rc << endl;
exit(-1);
}
}
//Have main thread wait for all other threads to stop running.
for(i = 0; i < NUM_THREADS; i++)
pthread_join(threads[i], NULL);
//cout << sharedcount << endl;
pthread_exit(NULL);
}
What you could do is use a counting semaphore (as opposed to a binary semaphore). A counting semaphore has an initial value greater than 1, allowing for multiple threads to call "wait" on the semaphore and not have those threads actually blocked and put in the semaphore queue.
What I would have done in your case is initialize a semaphore in the main function with an initial value of NUM_THREADS/2. Then I would insert a line at the beginning of threadedFunction where I do a wait(semaphore) and a line at the end of the function where you do a signal(semaphore). This way, when a thread is about to exit the function, it signals a thread that was blocked after having called wait on the semaphore and it lets this thread in.
Hope this helps.