Windows Thread Synchronization with create semaphore - multithreading

I am trying on a problem with writer and reader. I am trying with windows semaphore functionality.
It is very simple as follows
char n[200];
volatile HANDLE hSem=NULL; // handle to semaphore
The write function for console. Which release the semaphore for the read process.
void * write_message_function ( void *ptr )
{
/* do the work */
while(1){
printf("Enter a string");
scanf("%s",n);
ReleaseSemaphore(hSem,1,NULL); // unblock all the threads
}
pthread_exit(0); /* exit */
}
The print message wait for the release from the write message to print the message.
void * print_message_function ( void *ptr )
{
while(1){
WaitForSingleObject(hSem,INFINITE);
printf("The string entered is :");
printf("==== %s\n",n);
}
pthread_exit(0); /* exit */
}
The main function launch the application.
int main(int argc, char *argv[])
{
hSem=CreateSemaphore(NULL,0,1,NULL);
pthread_t thread1, thread2; /* thread variables */
/* create threads 1 and 2 */
pthread_create (&thread1, NULL, print_message_function, NULL);
pthread_create (&thread2, NULL, write_message_function, NULL);
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
/* exit */
CloseHandle(hSem);
}
The program executes but does not show the string input console.

ReleaseSemaphore in write_message_function will force the following:
The print_message_function will start the output and
The write_message_function will output and scan for input.
These two things occur at the same time. Using the semaphore to trigger the output is
fine. However, using MaximumCount=1 is a waste of capabilities, you may have mutiple inputs before an output occurs.
But the main problem here is that the I/O resources and the use of char n[200]; are not
implemented thread-safe. See What is meant by “thread-safe” code? for details. You'd still have to protect these resources by for example a mutex or a critical section.

Related

pthread_kill in multithread'd app causes segmentation fault

I managed to find several references to this problem which suggested pthread_kill was de-referencing the pthread_t structure which was causing some problem however other articles said this is not a problem as long as the pthread_t staructure is created via pthread_create.
Then I found a multi thread example of how to do this correctly :
How to send a signal to a process in C?
However I am still getting seg faults so here is my code example:
static pthread_t GPUthread;
static void GPUsigHandler(int signo)
{
fprintf(stderr, "Queue waking\n");
}
void StartGPUQueue()
{
sigset_t sigmask;
pthread_attr_t attr_obj; /* a thread attribute variable */
struct sigaction action;
/* set up signal mask to block all in main thread */
sigfillset(&sigmask); /* to turn on all bits */
pthread_sigmask(SIG_BLOCK, &sigmask, (sigset_t *)0);
/* set up signal handlers for SIGINT & SIGUSR1 */
action.sa_flags = 0;
action.sa_handler = GPUsigHandler;
sigaction(SIGUSR1, &action, (struct sigaction *)0);
pthread_attr_init(&attr_obj); /* init it to default */
pthread_attr_setdetachstate(&attr_obj, PTHREAD_CREATE_DETACHED);
GPUthread = pthread_create(&GPUthread, &attr_obj, ProcessGPUqueue, NULL);
if (GPUthread != 0)
{
fprintf(stderr, "Cannot start GPU thread\n");
}
}
void ProcessGPUqueue(void *ptr)
{
int sigdummy;
sigset_t sigmask;
sigfillset(&sigmask); /* will unblock all signals */
pthread_sigmask(SIG_UNBLOCK, &sigmask, (sigset_t *)0);
fprintf(stderr, "GPU queue alive\n");
while(queueActive)
{
fprintf(stderr, "Processing GPU queue\n");
while(GPUqueue != NULL)
{
// process stuff
}
sigwait(&sigmask, &sigdummy);
}
}
void QueueGPUrequest(unsigned char cmd, unsigned short p1, unsigned short p2, unsigned short p3, unsigned short p4)
{
// Add request to queue logic ...
fprintf(stderr, "About to Wake GPU queue\n");
pthread_kill(GPUthread, SIGUSR1);// Earth shattering KA-BOOM!!!
}

Trigger multiple pthreads by pthread_cond_broadcast

Since the examples for pthreads with pthread_cond_broadcast wakeup are sparse i wrote one, but are unsure if this is correctly synchronized and the way to do it:
do all threads share the same c and mtx variable?
is it necessary upon pthread_cond_wait return to test if some condition is actually met? in my case every call to broadcast should wake up every thread exactly once, but no-one else should do so. (do i prevent spurious wakeups?)
the program currently does not exit despite async cancel type. also no success with deferred cancellation tried in example code despite pthread_cond_wait being a cancellation point so.
overall does it work like i expect it to.
#include <pthread.h>
#include <iostream>
#include <unistd.h>
struct p_args{
int who;
};
pthread_cond_t c; //share between compilation units
pthread_mutex_t mtx;
void *threadFunc(void *vargs){
//pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,NULL);
struct p_args * args = (struct p_args *) vargs;
while(true){
//wait for trigger one loop
pthread_mutex_lock(&mtx);
pthread_cond_wait(&c, &mtx);
pthread_mutex_unlock(&mtx);
//should be entangled output showing concurrent execution
std::cout << "t " << args->who << std::endl;
/* expensive work */
}
delete args;
}
int main(int argc, char* argv[])
{
pthread_cond_init(&c, NULL);
pthread_mutex_init(&mtx, NULL);
pthread_t thread_id[2];
struct p_args *args0 = new p_args();
struct p_args *args1 = new p_args();
args0->who = 0;
args1->who = 1;
pthread_create(&thread_id[0], NULL, threadFunc, args0);
pthread_create(&thread_id[1], NULL, threadFunc, args1);
sleep(3);
pthread_mutex_lock(&mtx);
pthread_cond_broadcast(&c);
pthread_mutex_unlock(&mtx);
sleep(3);//test if thread waits
pthread_cancel(thread_id[0]);
pthread_cancel(thread_id[1]);
pthread_join (thread_id[0], NULL);
pthread_join (thread_id[1], NULL);
//could perform cleanup here
return 0;
}
Regarding exiting deferred:
thread_id[0] exits fine and i am stuck in line `pthread_join (thread_id[1], NULL);`, it says (Exiting) but seems stuck on a lock, with debugger:
<br>
[![enter image description here][2]][2]
<br>
EDIT final solution i came up with:
#include <pthread.h>
#include <iostream>
#include <unistd.h>
struct p_args{
int who;
};
pthread_cond_t c;
pthread_mutex_t mtx;
bool doSome[2];
bool exitFlag;
void *threadFunc(void *vargs){
struct p_args * args = (struct p_args *) vargs;
while(true){
//wait for trigger one loop
pthread_mutex_lock(&mtx);
do {
pthread_cond_wait(&c, &mtx);
if(exitFlag) {
std::cout << "return " << args->who << std::endl;
delete args;
pthread_mutex_unlock(&mtx);
return NULL;
}
} while(doSome == false);
doSome[args->who] = false;
pthread_mutex_unlock(&mtx);
std::cout << "t " << args->who << std::endl;
}
}
int main(int argc, char* argv[])
{
pthread_cond_init(&c, NULL);
pthread_mutex_init(&mtx, NULL);
pthread_t thread_id[2];
struct p_args *args0 = new p_args();
struct p_args *args1 = new p_args();
args0->who = 0;
args1->who = 1;
doSome[0] = doSome[1] = true;
exitFlag = false;
pthread_create(&thread_id[0], NULL, threadFunc, args0);
pthread_create(&thread_id[1], NULL, threadFunc, args1);
doSome[0] = doSome[1] = true;
pthread_cond_broadcast(&c);
sleep(3);
doSome[0] = doSome[1] = true;
pthread_cond_broadcast(&c);
sleep(3);
exitFlag = true;
pthread_cond_broadcast(&c);
pthread_join (thread_id[0], NULL);
pthread_join (thread_id[1], NULL);
return 0;
}
do all threads share the same c and mtx variable?
Yes, just like any other global variable. You could print their addresses from each thread to confirm it.
is it necessary upon pthread_cond_wait return to test if some condition is actually met?
Yes, all wait interfaces are subject to spurious wakeups, and you're always responsible for checking your own predicate. See the documentation or a good book.
the program currently does not exit ...
pthread_cancel is uniformly horrible and should never be used. It's really hard to get right. If you want to tell your thread to exit, write a notification mechanism - build it into the existing predicate loop - and signal/broadcast to make sure all threads wake up and realize it's time to die.
Regarding exiting deferred: thread_id[0] exits fine and i am stuck in line pthread_join (thread_id[1], NULL);, it says (Exiting) but seems stuck on a lock
One of the hard things about pthread_cancel is cleanup. If cancellation occurs while you're holding a lock, you need to have used pthread_cleanup_push to emulate cancel-compatible RAII semantics. Otherwise the first thread may (and in this case, did) die with the mutex still locked.
In this case the second thread is trying to exit from pthread_const_wait due to cancellation, but it needs to regain the lock and can't.
The usual form of a condition variable loop is this (and a good reference book should show something similar):
void *thread(void *data)
{
struct Args *args = (struct Args *)data;
/* this lock protects both the exit and work predicates.
* It should probably be part of your argument struct,
* globals are not recommended.
* Error handling omitted for brevity,
* but you should really check the return values.
*/
pthread_mutex_lock(&args->mutex);
while (!exit_predicate(args)) {
while (!work_predicate(args)) {
/* check the return value here too */
pthread_cond_wait(&args->condition, &args->mutex);
}
/* work_predicate() is true and we have the lock */
do_work(args);
}
/* unlock (explicitly) only once.
* If you need to cope with cancellation, you do need
* pthread_cleanup_push/pop instead.
*/
pthread_mutex_unlock(&args->mutex);
return data;
}
where your custom code can just go in bool exit_predicate(struct Args*), bool work_predicate(struct Args*) and void do_work(struct Args*). The loop structure itself rarely needs much alteration.

Linux Thread priority , behaviour is abnormal

In the below code snippet, I am creating 6 threads. Each with different priorities. The priority is mentioned in global priority array. I am doing a continuous increment of global variables inside each thread based on thread index. I was expecting the count to be higher if thread priority is higher. but my output is not adhering to priority concepts pl. refer to the output order shown below. I am trying this out on Ubuntu 16.04 and Linux kernel 4.10.
O/P,
Thread=0
Thread=3
Thread=2
Thread=5
Thread=1
Thread=4
pid=32155 count=4522138740
pid=32155 count=4509082289
pid=32155 count=4535088439
pid=32155 count=4517943246
pid=32155 count=4522643905
pid=32155 count=4519640181
Code:
#include <stdio.h>
#include <pthread.h>
#define FAILURE -1
#define MAX_THREADS 15
long int global_count[MAX_THREADS];
/* priority of each thread */
long int priority[]={1,20,40,60,80,99};
void clearGlobalCounts()
{
int i=0;
for(i=0;i<MAX_THREADS;i++)
global_count[i]=0;
}
/**
thread parameter is thread index
**/
void funcDoNothing(void *threadArgument)
{
int count=0;
int index = *((int *)threadArgument);
printf("Thread=%d\n",index);
clearGlobalCounts();
while(1)
{
count++;
if(count==100)
{
global_count[index]++;
count=0;
}
}
}
int main()
{
int i=0;
for(int i=0;i<sizeof(priority)/sizeof(long int);i++)
create_thread(funcDoNothing, i,priority[i]);
sleep(3600);
for(i=0;i<sizeof(priority)/sizeof(long int);i++)
{
printf("pid=%d count=%ld\n",getpid(),
global_count[i]);
}
}
create_thread(void *func,int thread_index,int priority)
{
pthread_attr_t attr;
struct sched_param schedParam;
void *pParm=NULL;
int id;
int * index = malloc(sizeof(int));
*index = thread_index;
void *res;
/* Initialize the thread attributes */
if (pthread_attr_init(&attr))
{
printf("Failed to initialize thread attrs\n");
return FAILURE;
}
if(pthread_attr_setschedpolicy(&attr, SCHED_FIFO))
{
printf("Failed to pthread_attr_setschedpolicy\n");
return FAILURE;
}
if (pthread_attr_setschedpolicy(&attr, SCHED_FIFO))
{
printf("Failed to setschedpolicy\n");
return FAILURE;
}
/* Set the capture thread priority */
pthread_attr_getschedparam(&attr, &schedParam);;
schedParam.sched_priority = sched_get_priority_max(SCHED_FIFO) - 1;
schedParam.sched_priority = priority;
if (pthread_attr_setschedparam(&attr, &schedParam))
{
printf("Failed to setschedparam\n");
return FAILURE;
}
pthread_create(&id, &attr, (void *)func, index);
}
The documentation for pthread_attr_setschedparam says:
In order for the parameter setting made by
pthread_attr_setschedparam() to have effect when calling
pthread_create(3), the caller must use pthread_attr_setinheritsched(3)
to set
the inherit-scheduler attribute of the attributes object attr to PTHREAD_EXPLICIT_SCHED.
So you have to call pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED) , for example:
if (pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED) != 0) {
perror("pthread_attr_setinheritsched");
}
pthread_create(&id, &attr, (void *)func, index);
Note: Your code produces a lot of compiler warnings, you need to fix those. You do not want to try to test code which have a lot of undefined behavior - as indicated by some of the warnings. You should probably lower the sleep(3600) to just a few seconds, since when you get your threads running under SCHED_FIFO, they will hog your CPU and the machine appears freezed while they are running.

Dead lock in the mutex, condition variable code?

I'm reading the book, Modern Operation Systems by AS TANENBAUM and it gives an example explaining condition variable as below. It looks to me there is a deadlock and not sure what I miss.
Lets assume consumer thread starts first. Right after the_mutex is locked, consumer thread is blocked waiting for the condition variable, condc.
If producer is running at this time, the_mutex will still be locked, because consumer never releases it. So producer will also be blocked.
This looks to me a textbook deadlock issue. Did I miss something here? Thx
#include <stdio.h>
#include <pthread.h>
#define MAX 10000000000 /* Numbers to produce */
pthread_mutex_t the_mutex;
pthread_cond_t condc, condp;
int buffer = 0;
void* consumer(void *ptr) {
int i;
for (i = 1; i <= MAX; i++) {
pthread_mutex_lock(&the_mutex); /* lock mutex */
/*thread is blocked waiting for condc */
while (buffer == 0) pthread_cond_wait(&condc, &the_mutex);
buffer = 0;
pthread_cond_signal(&condp);
pthread_mutex_unlock(&the_mutex);
}
pthread_exit(0);
}
void* producer(void *ptr) {
int i;
for (i = 1; i <= MAX; i++) {
pthread_mutex_lock(&the_mutex); /* Lock mutex */
while (buffer != 0) pthread_cond_wait(&condp, &the_mutex);
buffer = i;
pthread_cond_signal(&condc);
pthread_mutex_unlock(&the_mutex);
}
pthread_exit(0);
}
int main(int argc, char **argv) {
pthread_t pro, con;
//Simplified main function, ignores init and destroy for simplicity
// Create the threads
pthread_create(&con, NULL, consumer, NULL);
pthread_create(&pro, NULL, producer, NULL);
}
When you wait on a condition variable, the associated mutex is released for the duration of the wait (that's why you pass the mutex to pthread_cond_wait).
When pthread_cond_wait returns, the mutex is always locked again.
Keeping this in mind, you can follow the logic of the example.

How can a thread function access variables of the parent thread

I read that threads share the memory address space of it's parent thread.
If that is true , why can't a thread function access a local variable belonging to it's parent thread ?
void* PrintVar(void* arg){
printf( "%d\n", a);
}
int main(int argc, char*argv[]) {
int a;
a = 10;
pthread_t thr;
pthread_create( &thr, NULL, PrintVar, NULL );
}
If the thread shares the address space , then the function PrintVar should have been able to print the value of variable a , right ?
I read this piece of info on http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html
Threads in the same process share:
Process instructions
Most data
open files (descriptors)
signals and signal handlers
current working directory
User and group id
If that is true, then why does int a not qualify as a shared variable ?
I'd like to see an example code where the file descriptors are shared
The child thread can access the variable in the stack of the parent thread, it just needs to know the variable's address. For example, you could do it like this:
void* PrintVar(void* arg){
int * a = (int *) arg;
printf( "%d\n", *a);
}
int main(int argc, char*argv[]) {
int a;
a = 10;
pthread_t thr;
pthread_create( &thr, NULL, PrintVar, &a );
}
Note that this sort of thing can be tricky, since you have to (one way or another) guarantee that (a) won't get destroyed while the child thread is still accessing it. (In this case you'd probably want to call pthread_join() at the end of main(), so that the main thread will block there and not return from main() until after the child thread has exited)
you couldn't do that even if this were not a thread, because a is out of scope.
put a in the global scope, like so:
int a;
void* PrintVar(void* arg){
printf( "%d\n", a);
}
int main(int argc, char*argv[]) {
a = 10;
pthread_t thr;
pthread_create( &thr, NULL, PrintVar, NULL );
}
This is actually not an issue of threads. consider the following code:
void PrintVar(){
printf( "%d\n", a);
}
int main(int argc, char*argv[]) {
int a;
a = 10;
PrintVar();
}
This obviously won't work, because the variable name a declared in main is not visible in PrintVar, because it's in the local scope of another block. This is a compile-time problem, the compiler just doesn't know what you mean by a when you mention it in PrintVar.
But there is also another threading issue. when the main thread of a process exit, all other threads are terminated (specifically, when any thread calls _exit, then all threads are terminated, and _start calls _exit after main returns). but your main returns immediately after invoking the other thread. To prevent this, you should call pthread_join which will wait for a thread to exit before returning. that'll look like this
int a;
void* PrintVar(void* arg){
printf( "%d\n", a);
}
int main(int argc, char*argv[]) {
void *dummy;
a = 10;
pthread_t thr;
pthread_create( &thr, NULL, PrintVar, NULL );
pthread_join( thr, &dummy);
}

Resources