I'm doing some test on how a scheduler schedules a waiting thread and in the process, I want to not let OS to see a waiting thread, so I kill a thread which is waiting on a lock and start it when the lock is released, I think I should save the context of the thread before exiting and restore it when I create it again. Obviously I'm doing something wrong but I can't figure it out. (I'm very new to the subject.)
this is my code so far, it generates segmentation fault with setcontext.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <ucontext.h>
ucontext_t data;
pthread_t pth;
pthread_mutex_t lock1;
void* wake_up(void* arg) {
printf("going to wake up a thread\n");
setcontext(&data);
}
void MUTEX_UNLOCK(pthread_mutex_t* lock) {
pthread_mutex_unlock(lock);
pthread_create(&pth, NULL, wake_up, NULL);
}
void MUTEX_LOCK(pthread_mutex_t* lock) {
getcontext(&data);
while(1) {
if(pthread_mutex_trylock(lock) == 0) {
printf("got the lock\n");
break;
}
else {
printf("going to exit thread\n");
pthread_exit(NULL);
}
}
}
void* routine1(void* param) {
MUTEX_LOCK(&lock1);
printf("enter any character to continue\n");
getchar();
MUTEX_UNLOCK(&lock1);
}
int main(int argc, char** argv) {
pthread_mutex_init(&lock1, 0);
pthread_t thread1[2];
int i;
for (i = 0; i < 2; i++)
pthread_create(&thread1[i], NULL, routine1, NULL);
while(1);
}
setcontext is not valid when setting the context of a thread which has exited. (The stack pointer points into a stack which has been freed.) So that's why you're getting a crash.
More in general, getcontext and setcontext are obsolete and extremely strange functions that should not be used unless you have very specific needs regarding cooperative (non-pthreads) multithreading. While you haven't described what you're trying to do, I'm 99% certain that you don't need setcontext to do it.
Related
I have new data appearing over a bus. I want my main thread to "wake up" when the new data arrives. My original version of the code is this:
#include <time.h>
#include <stdio.h>
#include <pthread.h>
#include <time.h>
int data = 0;
void* thread_func(void* args)
{
while(1)
{
sleep(2);
data = random() % 5;
}
return NULL;
}
int main()
{
int tid;
pthread_create(&tid, NULL, &thread_func, NULL);
while(1)
{
// Check data.
printf("New data arrived: %d.\n", data);
sleep(2);
}
return 0;
}
But clearly an infinite while loop in the main thread is overkill. So I thought how about this?
#include <time.h>
#include <stdio.h>
#include <pthread.h>
#include <time.h>
int data = 0;
pthread_mutex_t mtx;
void* thread_func(void* args)
{
while(1)
{
sleep(2);
// Data has appeared and can be read by main().
data = random() % 5;
pthread_mutex_unlock(&mtx);
}
return NULL;
}
int main()
{
int tid;
pthread_mutex_init(&mtx, NULL);
pthread_create(&tid, NULL, &thread_func, NULL);
while(1)
{
pthread_mutex_lock(&mtx);
printf("New data has arrived: %d.\n", data);
}
return 0;
}
This works, but is it the best way?
In actual fact, I don't just have a main thread, but several threads that I would like to be asleep until new data for them arrived. This would involve using one mutex lock for each thread. Is this the best way to do things?
I hope it's clear. Thanks.
You can use pthread_cond_wait to wait for a change on the data you share between your threads. This function automatically blocks your mutex and you have to release it afterwards. To notify your threads that the data is ready use the pthread_cond_signal function.
But be careful, you must always lock and unlock your mutex in each of your threads, not as you do in your example.
I'm new to C and I am trying to learn. I'm trying to implement multithreading in my program, but I'm having problems. The program (and the threads) should be going on running in a infinite loop, but actually the programs stops after few seconds. What can I do for having the program running forever? Am I doing something wrong?
#include <stdio.h>
#include <pthread.h>
void *func(void *threadid){
while (1)
{
/* do stuff, but the program terminates after that thread does few cycles */
}
}
int main(){
#define NUM_THREADS 800
pthread_t threads[NUM_THREADS];
int rc, i;
for (i=0; i < NUM_THREADS; i++)
{
rc = pthread_create(&threads[i], NULL, func, (void *)i);
if (rc)
{
printf("Error to create thread, #%d\n", rc);
exit(-1);
}
}
pthread_exit(NULL);
}
As soon as your main thread exits, the program terminates (and so do the threads). If you want your program to never end, you should add a while(1); at the end of you main while loop.
Note that this is not how to do it properly, your threads should have an end, and the master thread should wait for all the threads to be done, before exiting itself.
I've spent quite a few hours on trying to figure this one out and I'm completly stuck. The program is supposed to start 6 threads. Where some threads start where others end. Right now, I'm trying to get one single thread (thread 0) to execute. The caps lock commenting shows where I have added code and done my mistakes. My main struggle here is dealing with the pointers. Could anyone give me any pointers (ha..ha.. :c )?
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#define SHARED 1
sem_t sem[6];
struct threadargs
{
int id; /* thread number */
int sec; /* how many sec to sleep */
int signal[6]; /* which threads to signal when done */
};
void *tfunc(void *arg)
{
int i;
struct threadargs *targs=arg;
sem_wait(sem); //WAIT FOR OWN SEMAPHORE
printf("Thread %d is running\n", targs->id);
sleep(targs->sec);
printf("Thread %d is completed and may wake others..\n", targs->id);
for(i=0; i<6; i++) //ITERATE OVER signal_ARRAY &
{ //WAKE THREAD NUMBER i IF
if(targs->signal[i] == 1) //signal[i] IS 1
pthread_cond_signal(&sem[i]);
}
}
int main(void)
{
int i, j;
struct threadargs *targs[6];
pthread_t tid[6];
for(i=0; i<6; i++)
{
targs[i] = (struct threadargs*) malloc(sizeof(struct threadargs));
for(j=0; j<6; j++)
{ targs[i]->signal[j]=0; }
}
targs[0]->id=1;
targs[0]->sec=1;
targs[0]->signal[1]=1;
targs[0]->signal[4]=1;
sem[0] = 0; //INITIALIZE THREAD'S SEMAPHORE TO 0 or 1
pthread_create(targs[0], NULL, tfunc, NULL) // START THREAD
for(i=0; i<6; i++)
pthread_join(tid[i], NULL);
return 0;
}
Alright. First things first, I do recommend taking a second look at your coding style. It is of course highly subjective and I won't say yours is bad, but it took me a while to figure it out (if you really want to know, I recommend the Linux coding style for C/C++ code).
Lets get on with your problem. As far as I can see, the main issue seems that you're basically comparing pointers to apples with pointers to banana's (in other words, you're using the wrong pointer type in the wrong place).
To make sure that calls to functions and the like are correct, make sure to look up the API documentation for functions that are new to you (examples: pthread_create, sem_init, sem_wait, sem_post, pthread_cond_signal).
As you can see, pthread_cond_signal doesn't take a sem_t* as argument, and therefore you can't pass one to it and expect it to work. Below you'll find an example program showing how semaphores are used.
First, a new thread is created which will be put in waiting state instantly. As soon as the main tread finished counting from 0 to 150, it will post ('unlock') the semaphore and allowing the second thread to finish its execution.
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
static sem_t sem_thread_one;
static pthread_t thread_one_data;
static int x;
static void *tfunc(void *arg)
{
sem_wait(&sem_thread_one);
printf("Thread 1 is running. The value of x is %i\n", x);
return NULL;
}
int main(int argc, char **argv)
{
sem_init(&sem_thread_one, 0 /* don't share between processes */, 0);
if(pthread_create(&thread_one_data, NULL, &tfunc, NULL)) {
fprintf(stderr, "Could not create thread, exiting!\n");
return -EXIT_FAILURE;
}
while(x < 150) {
x++;
}
sem_post(&sem_thread_one);
if(pthread_join(thread_one_data, NULL)) {
fprintf(stderr, "Could not join threads, exiting!\n");
return -EXIT_FAILURE;
}
sem_destroy(&sem_thread_one);
printf("Program ran succesfully!\n");
return -EXIT_SUCCESS;
}
Save in a file sem.c and compile & link using:
gcc -Wall -Os -pthread -o sem_test sem.c
Now a second example, but now using pthread_cond_t. The functionality of the program is somewhat similar, it waits for a counter to reach a certain number.
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <pthread.h>
static pthread_t thread_one_data, thread_two_data;
static volatile int x, y, idx = 10;
static int count = 1;
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t condition = PTHREAD_COND_INITIALIZER;
static void *cond_test_wait(void *arg)
{
pthread_mutex_lock(&mutex);
while(count < 10) {
printf("Waiting for `count < 10' to become true\n");
pthread_cond_wait(&condition, &mutex);
}
pthread_mutex_unlock(&mutex);
printf("Test wait thread finished. Value of count: %i\n", count);
return NULL;
}
static void *cond_test_signal(void *arg)
{
while(count < 10) {
pthread_mutex_lock(&mutex);
pthread_cond_signal(&condition);
/* do more intelligent things here */
count++;
pthread_mutex_unlock(&mutex);
}
printf("Test signal thread finished\n");
return NULL;
}
int main(int argc, char **argv)
{
if(pthread_create(&thread_one_data, NULL, &cond_test_wait, NULL)) {
fprintf(stderr, "Could not create thread, exiting!\n");
return -EXIT_FAILURE;
}
if(pthread_create(&thread_two_data, NULL, &cond_test_signal, NULL)) {
fprintf(stderr, "Could not create thread, exiting!\n");
return -EXIT_FAILURE;
}
pthread_join(thread_one_data, NULL);
pthread_join(thread_two_data, NULL);
pthread_cond_destroy(&condition);
pthread_mutex_destroy(&mutex);
printf("Program ran succesfully!\n");
return -EXIT_SUCCESS;
}
Save in a file cond.c and compile & link using:
gcc -o cond -pthread -Os -Wall cond.c
Do note how neat condition work in this example. You can use them to wait until any expression (= condition) becomes true. After the condition becomes true normal execution continue's.
If you need any more help, don't hesitate to ask in the comments. Good luck combining the above examples to fix up your program.
I'm actually new in processes, threads, semaphores, ipc etc(shortly operating system operations on Linux)... My problem is that I compile my code and It simply gets stuck at so funny points. Processes are executed, but they can't enter their threads' function. After that, program directly ends without doing something. I really can't figure out the problem is here or everything have problem. I don't know.
#define _GNU_SOURCE
#include <sys/types.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
void * function1(void *ptr)
{
printf("Function 1\n"); //!Test prints
printf("Index is %d",*((int *)ptr));
sleep(1);
pthread_exit(NULL);
}
void * function2(void *ptr)
{
printf("Function 2\n"); //!Test prints
printf("Index is %d",*((int *)ptr));
sleep(2);
pthread_exit(NULL);
}
int main(){
//...
int *index;
int i;
pid_t f;
int number_of_process=5;
pthread_t thread1, thread2;
//...
for(i=0; i<number_of_process; i++)
{
f=fork();
if(f==-1)
{
printf("Fork Error!!\n");
exit(1);
}
if(f==0) //To block child processes re-enter
{
*index = i; //I store index number for each process here. I'll need them in the thread functions
break;
}
}
/*******************PARENT PROCESS********************/
if(f!=0){
// wait for all children to exit
while (f = waitpid (-1, NULL, 0)){
if (errno == ECHILD)
break;
}
exit(0);
}
/*******************CHILD PROCESS*********************/
else{
pthread_create(&thread1,NULL,function1,(void *)index);
pthread_create(&thread2,NULL,function2,(void *)index);
}
}
Processes are executed, but they can't enter their threads' function.
After that, program directly ends without doing something.
That's because the main thread (i.e. child process created by fork()) doesn't wait for the threads to complete their execution. So it gives you the impression that the program exits without calling all pthread functions.
Use pthread_join() after creating threads:
...
pthread_create(&thread1,NULL,function1,(void *)index);
pthread_create(&thread2,NULL,function2,(void *)index);
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
...
The output may be interleaved due to threads printing without any synchronization.
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.