macos - macOS's pthread PTHREAD_CANCEL_ASYNCHRONOUS not working - c

I am using the following code:
#include <unistd.h>
#include <pthread.h>
#include <stdio.h>
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
void
clean(void *arg)
{
printf("thread clean: %ld\n", (unsigned long)arg);
}
void*
thread_template(void *arg)
{
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
pthread_cleanup_push(clean, (void*)pthread_self());
printf("thread: %ld\n", (unsigned long)pthread_self());
while ( 1 ) {}
pthread_cleanup_pop(0);
pthread_exit((void*)0);
}
int
main(int argc, char const *argv[]) {
pthread_t tid;
pthread_create(&tid, NULL, thread_template, NULL);
// waiting for 2 seconds
sleep(2);
pthread_cancel(tid);
pthread_join(tid, NULL);
}
It works fine both on FreeBSD 11 and Ubuntu 16,
outputs are like this:
thread: 1994462320
thread clean: 1994462320
But on macOS, it seems pthread_cancel() doesn't affect the thread, main thread blocks at pthread_join(), the clean function never execute(only the first row was output).
So, what happened to macOS's pthread? or any wrong with my code ?

Related

I am trying to create a new c file that is a modified version of another file, nosmp.c, while also adding semaphore system calls

This is the code I have so far for the newly modified version of nosmp.c.
#include <pthread.h>
#include <stdio.h>
#define NUM_THREADS 5
void *PrintHello(void *threadid)
{
long tid;
tid = (long)threadid;
printf("Hello World! It's me, thread #%ld!\n", tid);
pthread_exit(NULL);
}
int main (int argc, char *argv[])
{
pthread_t threads[NUM_THREADS];
int rc;
lng t;
for(t=0; t<NUM_THREADS; t++){
printf("In main: creating thread %ld\n", t);
rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t);
if (rc){
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
pthread_exit(NULL);
}
The code below is the old nosmp.c code:
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
void* thread(void* arg)
{
printf("\n Entered.., %c\n", *((char*)arg));
//critical section
sleep(4);
printf("\n Just Exiting.., %c\n", *((char*)arg));
}
int main()
{
pthread_t t1,t2;
pthread_create(&t1,NULL,thread,"1");
sleep(2);
pthread_create(&t2,NULL,thread,"2");
pthread_join(t1,NULL);
pthread_join(t2,NULL);
return 0;
}
For the modified version of the code above, I am trying to figure out where I would add the semaphore system calls into their proper lines to ensure that two threads will enter the critical section in order.

Execution of pthreads in particular order?

I am been trying to write a program (for learning) in which there will be two threads (A and B) and both threads should execute one after the another. For example, if threads just display/prints Thread A and Thread B, then they should print in that particular order forever.
The desired output is
In Thread: thread1
In Thread: thread2
In Thread: thread1
In Thread: thread2
....
The program that I have wrote uses conditional variables for synchronisation. I have tired mutex and semaphore but they do guarantee mutual exclusivity but they don't print the information in a particular order. I understand that issue is related to scheduling of the threads by scheduler and it is possible that the thread which has just released the mutex, can lock it again immediately. See this link for link for more information.
#include <stdio.h>
#include <ctype.h>
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include <unistd.h>
#include <semaphore.h>
#include <pthread.h>
pthread_cond_t cond;
pthread_mutex_t mutex;
int thread1_ret = 0;
void *thread1(void *arg)
{
while (1) {
pthread_mutex_lock(&mutex);
pthread_cond_wait(&cond, &mutex);
printf("In Thread: %s\r\n", __func__);
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
}
thread1_ret = 5;
return &thread1_ret;
}
int thread2_ret = 0;
void *thread2(void *arg)
{
pthread_mutex_lock(&mutex);
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
while (1) {
pthread_mutex_lock(&mutex);
pthread_cond_wait(&cond, &mutex);
printf("In Thread: %s\r\n", __func__);
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
}
thread2_ret = 5;
return &thread2_ret;
}
int main(int argc, char *argv[])
{
pthread_t t1, t2;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
pthread_cond_init(&cond, NULL);
pthread_mutex_init(&mutex, NULL);
pthread_create(&t1, &attr, thread1, NULL);
pthread_create(&t2, &attr, thread2, NULL);
pthread_attr_destroy(&attr);
void *ret;
pthread_join(t1, &ret);
printf("Thread Returned: %d\r\n", *(int *)ret);
pthread_join(t2, &ret);
printf("Thread Returned: %d\r\n", *(int *)ret);
return 0;
}
My program is working properly but it stops printing after some time (2-3 seconds). I couldn't locate the bug in my code. It would be great if someone direct me with some other solution to achieve the same thing in more efficient and standard method (if there are other standard and efficient methods to solve such problem statement).
Condition variable notifications get lost when no thread is waiting in pthread_cond_wait and spurious wakes-ups happen, so the code must rather wait for a change of a shared state.
Working example:
#include <stdio.h>
#include <ctype.h>
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include <unistd.h>
#include <semaphore.h>
#include <pthread.h>
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
unsigned state = 0;
int thread1_ret = 0;
void *thread1(void *arg)
{
unsigned state_copy;
pthread_mutex_lock(&mutex);
state_copy = state;
pthread_mutex_unlock(&mutex);
while(1) {
pthread_mutex_lock(&mutex);
while(state_copy == state)
pthread_cond_wait(&cond, &mutex);
state_copy = ++state;
printf("In Thread: %s\r\n", __func__);
pthread_mutex_unlock(&mutex);
pthread_cond_signal(&cond);
}
thread1_ret = 5;
return &thread1_ret;
}
int thread2_ret = 0;
void *thread2(void *arg)
{
unsigned state_copy;
pthread_mutex_lock(&mutex);
state_copy = ++state;
pthread_mutex_unlock(&mutex);
pthread_cond_signal(&cond);
while (1) {
pthread_mutex_lock(&mutex);
while(state_copy == state)
pthread_cond_wait(&cond, &mutex);
state_copy = ++state;
printf("In Thread: %s\r\n", __func__);
pthread_mutex_unlock(&mutex);
pthread_cond_signal(&cond);
}
thread2_ret = 5;
return &thread2_ret;
}
int main(int argc, char *argv[])
{
pthread_t t1, t2;
pthread_create(&t1, NULL, thread1, NULL);
pthread_create(&t2, NULL, thread2, NULL);
void *ret;
pthread_join(t1, &ret);
printf("Thread Returned: %d\r\n", *(int *)ret);
pthread_join(t2, &ret);
printf("Thread Returned: %d\r\n", *(int *)ret);
return 0;
}
Note that the above code signals the condition variable after releasing the mutex. That is a micro-optimization, however, if FIFO order in waking up waiting threads is required then the mutex must be locked while signalling. See pthread_cond_signal:
The pthread_cond_broadcast() or pthread_cond_signal() functions may be called by a thread whether or not it currently owns the mutex that threads calling pthread_cond_wait() or pthread_cond_timedwait() have associated with the condition variable during their waits; however, if predictable scheduling behavior is required, then that mutex shall be locked by the thread calling pthread_cond_broadcast() or pthread_cond_signal().

Simple multithreading program with emscripten

I am trying to create a simple program with thread support using Emscripten:
#include <stdio.h>
#include <pthread.h>
void *myThreadFun(void *vargp) {
printf("From Thread \n");
return NULL;
}
int main(int argc, char *argv[]) {
pthread_t tid;
printf("Before Thread\n");
pthread_create(&tid, NULL, myThreadFun, NULL);
printf("Before join\n");
pthread_join(tid, NULL);
printf("After Thread\n");
return 0;
}
I am executed it in Firefox and I compile using -s USE_PTHREADS=1.
This is the output I got in the console:
Before Thread
Preallocating 1 workers for a pthread spawn pool.
Before join
But I expected:
Before Thread
Preallocating 1 workers for a pthread spawn pool.
Before join
After Thread
It is like the thread is not ending. Am I missing something?
I had the same issue. I fixed it by compiling with -s PTHREAD_POOL_SIZE=x with x = number of thread created.

Threads in c, what am I missing here?

I'm trying to create a thread, and I cannot figure out what I am doing wrong here. It's very basic, I just want to make sure I can get the thread created before I delve into what I'll be doing in the thread. Here's my code.
//prog.c
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <pthread.h>
#include <stdbool.h>
#include <unistd.h>
int threadCount =0; //Global variable to hold our thread counter
//this is the function that gets called when a thread is created
void *threadCreate(void* arg){
printf("Thread #%d has been created\n", threadCount);
threadCount++;
int param = (int)arg;
printf("We were sent: %d\n", param);
printf("Now the thread will die\n");
threadCount--;
pthread_exit(NULL);
}
//main
int main(int argc, char *argv[]){
pthread_t tid;
int numski = 50;
int res;
res = pthread_create(&tid, NULL, threadCreate, (void*)numski);
if (res){
printf("Error: pthread_create returned %d\n", res);
exit(EXIT_FAILURE);
}
return 0;
}
I am compiling using the following command:
gcc -Wall -pthread -std=c99 prog.c -o Prog
And when I try to run it, I get no output at all.
Main is exiting right away, and therefore your process is dying right away. End it with pthread_join to wait for them. Here is one example I googled, which contains the following example code:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void *print_message_function( void *ptr );
main()
{
pthread_t thread1, thread2;
const char *message1 = "Thread 1";
const char *message2 = "Thread 2";
int iret1, iret2;
/* Create independent threads each of which will execute function */
iret1 = pthread_create( &thread1, NULL, print_message_function, (void*) message1);
iret2 = pthread_create( &thread2, NULL, print_message_function, (void*) message2);
/* Wait till threads are complete before main continues. Unless we */
/* wait we run the risk of executing an exit which will terminate */
/* the process and all threads before the threads have completed. */
pthread_join( thread1, NULL);
pthread_join( thread2, NULL);
printf("Thread 1 returns: %d\n",iret1);
printf("Thread 2 returns: %d\n",iret2);
exit(0);
}
void *print_message_function( void *ptr )
{
char *message;
message = (char *) ptr;
printf("%s \n", message);
}

Problem while compiling pthreads program

I tried to compile this simple pthreads program with this command
$ gcc -pthread -o pthreads pthreads.c
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
void *myThread(void *arg);
int main()
{
pthread_t mythread;
int ret;
ret = pthread_create( &mythread, NULL, myThread, NULL );
if (ret != 0){
printf( "Can't create pthread: %s", strerror(errno));
exit(-1);
}
return 0;
}
void *myThread(void *arg){
// Thread code goes here..
printf("OK! NOW ON THE THREAD\n");
pthread_exit(NULL);
}
but when trying ./pthreads there is no output presented!!
You need to wait for the thread to finish. Otherwise you risk exiting before the thread starts executing.
...
pthread_create( &mythread, NULL, myThread, NULL );
...
// Wait for the thread to finish.
pthread_join( mythread, NULL);
You didn't wait for your thread to finish. You need to use pthread_join().
You problem comes from the fact that you're main thread is returning from main, and thus calling exit (or _exit). All running thread are killed when the program exit. In this case, the worker thread didn't have the time to execute before it is killed.
You can use pthread_join to wait for the completion of the thread before returning from main.
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
void *myThread(void *arg);
int main()
{
void* thread_return;
pthread_t mythread;
int ret;
ret = pthread_create(&mythread, NULL, myThread, NULL);
if (ret != 0)
{
printf("Can't create pthread: %s\n", strerror(errno));
exit(-1);
}
ret = pthread_join(mythread, &thread_return);
if (ret != 0)
{
printf("Can't join pthread: %s\n", strerror(errno));
exit(-1);
}
return 0;
}
void *myThread(void *arg)
{
printf("OK! NOW ON THE THREAD\n");
pthread_exit(NULL);
}
Sanjit's answer is certainly correct, but for the sake of enlarging your threads toolbox, you might also look at pthread_barrier_wait. When you have a simple program with a lot of threads and main looks like "start all worker threads and wait for them to finish", having main and all the workers simply wait on a barrier can be a nice way to avoid having to store all the worker thread ids and join them in a for loop. Barriers also have a lot of other neat uses that sometimes let you avoid unnecessary complexity from doing the same things with mutexes and condition variables.

Resources