I have this code, I am trying to create n threads, Do some work in each thread, and then reap each thread. If n thread is even, use detach, and if odd, use join,
When i run the program, it first prints out Successfully reaped thread, then doing working, then successfully reaped thread... looks like i have some synchronization issues
Do I even need to use Mutex?
Can anyone help me with getting everything running in the right order?
Thank you
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
pthread_mutex_t lock;
void *dowork(){
//Do whatever needs to be done in each thread here
pthread_mutex_lock(&lock);
long tid = (long) pthread_self();
printf("Doing Work ...for %ld\n",tid);
pthread_mutex_unlock(&lock);
//pthread_exit(NULL);
return;
}
void spawn(int n){
if (pthread_mutex_init(&lock, NULL) != 0)
{
printf("\n mutex init failed\n");
exit (1);
}
int i=0;
//pthread_t * thread = malloc(sizeof(pthread_t)*n);
pthread_t threads[n];
while (i<n) {
if(pthread_create(&(threads[i]), NULL, dowork, NULL) != 0){
printf ("Create pthread error!\n");
exit (1);
}
i++;
}//End of while
// Wait for threads to complete //
i = 0;
while (i<n)
{
int success = -1;
if(i%2 == 0){
success=pthread_detach(threads[i]);
}
else{
success=pthread_join(threads[i], NULL);
}
if(success==0)
printf("Succesfully reaped thread\n");
i++;
}
pthread_mutex_destroy(&lock);
}
int main() {
spawn(5);
}
Related
i have little trouble with pthread priority.I have set scheduler FIFO. I have 2 thread, each have diffretnt priority. On my project when i push A or B, one thread start working. Thats fine, but when one thread working and push again B(priority15) and then A(priority 20) my assumption is that thread A jumps before B in stack queue and after first thread will by next thread A with priority 20 and then thread B (15). Is that problem FIFO or something else?
PS: I dont want use semaphore, i want to solve it just with priority and scheduler. Thanks
#include <stdio.h>
#include<pthread.h>
#include<semaphore.h>
#include<unistd.h>
#include <time.h>
#include <sched.h>
sem_t mutex;
void* levelOnefunction(void *a)
{
sem_wait(&mutex);
int* b = (int *) a;
printf("Thread! next main!\n");
printf("sched prior:%d\n",*b);
sleep(3);
sem_post(&mutex);
return 0;
}
int main()
{
char s;
pthread_t t;
pthread_attr_t tattr;
struct sched_param param;
sem_init(&mutex,0,1);
pthread_attr_init(&tattr);
if(pthread_attr_setschedpolicy(&tattr,SCHED_FIFO)!=0)
printf("ERROR FIFO!\n");
//pthread_setschedparam(t,SCHED_FIFO,¶m);
if(pthread_attr_getschedparam(&tattr,¶m)!=0)
printf("ERROR attr get sheduler!\n");
/* int k =pthread_attr_setinheritsched(&tattr,PTHREAD_EXPLICIT_SCHED);
if (k!=0)
printf("ERROR\n"); */
printf("Initial priority is %d \n",param.sched_priority);
int min = sched_get_priority_min(SCHED_FIFO);
int max = sched_get_priority_max(SCHED_FIFO);
printf("MIN - %d ---> MAX - %d\n",min,max);
scanf("%c",&s);
while (s != '\0')
{
if(s=='a')
{
printf("a\n");
param.sched_priority=20;
if(pthread_attr_setschedparam(&tattr,¶m)!=0)
printf("ERROR attr_setschedul!\n");
printf("update priority is:%d\n",param.sched_priority);
if(pthread_create(&t,&tattr,levelOnefunction,(void *)¶m.sched_priority)!=0)
printf("ERROR thread1\n");
pthread_join(t,NULL);
printf("main finish!\n");
printf("%c end\n\n",s);
}
else if(s=='b')
{
printf("b\n");
param.sched_priority=15;
if(pthread_attr_setschedparam(&tattr,¶m)!=0)
printf("ERROR attr_setschedul!\n");
if(pthread_create(&t,&tattr,levelOnefunction,(void *)¶m.sched_priority)!=0)
printf("ERROR Thread 2 ");
pthread_join(t,NULL);
printf("main finish!\n");
printf("%c end\n\n",s);
}
else if(s=='\n')
{
}
else if (s!='a' && s!='b')
{
printf("bad key\n");
}
scanf("%c",&s);
}
sem_destroy(&mutex);
return 0;
}
You are calling pthread_join() in the main thread immediately after creating each child thread.
This means that you never have more than one child thread created at a time - after creating one child thread, the main thread will then block in pthread_join() until that child thread is complete. Only then does it call scanf() again and potentially create another child thread.
Thread priorities don't come into it.
I am writing various code snippets and see what happens. The code below was intended to delay all threads until all reached a certain point in the code and then make each print a distinctive number. Since the threads all do that, the numbers should occur in a random order.
My current problem is that I keep they threads busy waiting. If the number of threads gets big, the program slows down significantly.
I would like to change that by using signals, I found pthread_cond_wait() for that, however I don't see how one would use that to signal all threads that they would please wake up.
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#define threads 10
int counter=0;
pthread_mutex_t lock;
void handler(void *v) {
pthread_mutex_lock(&lock);
counter++;
printf("%d\n", counter);
pthread_mutex_unlock(&lock);
while(counter != threads); // busy waiting
printf("I am first! %d\n", v);
}
int main() {
pthread_t t[threads];
for(int i =0; i < threads; i++) {
pthread_create(&t[i], NULL, handler, (void*) i);
}
for(int i =0; i < threads; i++) {
pthread_join(t[i], NULL);
}
return 0;
}
EDIT: I changed the code to the following, however, it still does not work :/
pthread_mutex_t lock;
pthread_cond_t cv;
void handler(void *v) {
pthread_mutex_lock(&lock);
pthread_cond_wait(&cv, &lock);
printf("I am first! %d\n", v);
pthread_mutex_unlock(&lock);
}
int main() {
pthread_t t[threads];
for(int i =0; i < threads; i++)
pthread_create(&t[i], NULL, handler, (void*) i);
sleep(2);
pthread_cond_signal(&cv);
for(int i =0; i < threads; i++)
pthread_join(t[i], NULL);
return 0;
}
use broadcast()?
http://pubs.opengroup.org/onlinepubs/009696699/functions/pthread_cond_broadcast.html
The pthread_cond_broadcast() function shall unblock all threads currently blocked on the specified condition variable cond.
The pthread_cond_signal() function shall unblock at least one of the threads that are blocked on the specified condition variable cond (if any threads are blocked on cond).
An alternative solution to pthread_cond_broadcast() might be the following.
You define a read-write mutex and lock it in write in the main thread before creating the other threads. The other threads will try to acquire a read-lock but since the main thread have a write-lock they will be blocked.
After the creation of all thread the main-thread releases the lock. All the other threads will be waken up and since many read-locks can coexist the will execute simultaneously (i.e. no one will be locked).
Code might be something like:
pthread_rwlock_t lock;
void handler(void *v) {
if ((res = pthread_rwlock_rdlock(&lock)!=0)
{
exit(1);
}
printf("I am first! %d\n", v);
pthread_rwlock_unlock(&lock);
}
int main() {
pthread_t t[threads];
//First acquire the write lock:
if ((res = pthread_rwlock_wrlock(&lock)!=0)
{
exit(1);
}
for(int i =0; i < threads; i++)
{
pthread_create(&t[i], NULL, handler, (void*) i);
//it is not clear if you want sleep inside the loop or not
// You indented it as if to be inside but not put brackets
sleep(2);
}
pthread_rwlock_unlock(&lock);
for(int i =0; i < threads; i++)
pthread_join(t[i], NULL);
pthread_rwlock_destroy(&lock);
return 0;
}
Try posting the matching remove_from_buffer code.
Better yet, Short, Self Contained, Correct Example
Make a short main() with two threads.
One thread adds to the buffer at random intervals.
The other thread removes from the buffer at random intervals.
Example
CELEBP22
/* CELEBP22 */
#define _OPEN_THREADS
#include <pthread.h>
#include <stdio.h>
#include <time.h>
#include <unistd.h>
pthread_cond_t cond;
pthread_mutex_t mutex;
int footprint = 0;
void *thread(void *arg) {
time_t T;
if (pthread_mutex_lock(&mutex) != 0) {
perror("pthread_mutex_lock() error");
exit(6);
}
time(&T);
printf("starting wait at %s", ctime(&T));
footprint++;
if (pthread_cond_wait(&cond, &mutex) != 0) {
perror("pthread_cond_timedwait() error");
exit(7);
}
time(&T);
printf("wait over at %s", ctime(&T));
}
main() {
pthread_t thid;
time_t T;
struct timespec t;
if (pthread_mutex_init(&mutex, NULL) != 0) {
perror("pthread_mutex_init() error");
exit(1);
}
if (pthread_cond_init(&cond, NULL) != 0) {
perror("pthread_cond_init() error");
exit(2);
}
if (pthread_create(&thid, NULL, thread, NULL) != 0) {
perror("pthread_create() error");
exit(3);
}
while (footprint == 0)
sleep(1);
puts("IPT is about ready to release the thread");
sleep(2);
if (pthread_cond_signal(&cond) != 0) {
perror("pthread_cond_signal() error");
exit(4);
}
if (pthread_join(thid, NULL) != 0) {
perror("pthread_join() error");
exit(5);
}
}
OUTPUT
starting wait at Fri Jun 16 10:54:06 2006 IPT is about ready to
release the thread wait over at Fri Jun 16 10:54:09 2006
I'm playing with Posix threads and have written the following code in which I create a lot of threads, but reuse pthread_t variables for this purpose:
#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
// The amount of thread creation iterations
static const int N = 300;
static pthread_t thread_1, thread_2, thread_3;
void * logic_1(void * arg)
{
usleep(1 * 1000);
printf("logic_1 end\n");
return 0;
}
void * logic_2(void * arg)
{
usleep(1 * 1000);
printf("logic_2 end\n");
return 0;
}
void * logic_3(void * arg)
{
usleep(1 * 1000);
printf("logic_3 end\n");
return 0;
}
int main()
{
int counter = 0;
int i;
for(i = 0; i < N; ++i)
{
if (pthread_create(&thread_1, NULL, &logic_1, NULL) != 0)
{
perror("error: ");
printf("thread1 did not start after %d threads that were started\n", counter);
break;
}
else
{
++counter;
printf("start %d thread\n", counter);
}
if (pthread_create(&thread_2, NULL, &logic_2, NULL) != 0)
{
perror("error: ");
printf("thread2 did not start after %d threads that were started\n", counter);
break;
}
else
{
++counter;
printf("start %d thread\n", counter);
}
if (pthread_create(&thread_3, NULL, &logic_3, NULL) != 0)
{
perror("error: ");
printf("thread3 did not start after %d threads that were started\n", counter);
break;
}
else
{
++counter;
printf("start %d thread\n", counter);
}
usleep(500 * 1000);
}
pthread_join(thread_1, NULL);
pthread_join(thread_2, NULL);
pthread_join(thread_3, NULL);
return 0;
}
and after executing I got the error:
...
start 376 thread
start 377 thread
start 378 thread
logic_3 end
logic_2 end
logic_1 end
start 379 thread
start 380 thread
start 381 thread
logic_3 end
logic_2 end
logic_1 end
error: : Cannot allocate memory
thread1 did not start after 381 threads that were started
Can you tell me what I'm doing wrong? I think that I faced with some boundaries or limitation in linux? Will resources for the thread be deallocated or not after each call of return 0; statement in logic_1, logic_2, logic_3 functions? Maybe I should use an array of threads and for each item of this array call the pthread_join function?
You should call pthread_join inside loop rather than outside so that resources for allocated are released before new set of threads are started in next iteration
If you dont join the thread you are losing system resources as per pthread_join man page
Failure to join with a thread that is joinable (i.e., one that is not
detached), produces a "zombie thread". Avoid doing this, since each
zombie thread consumes some system resources, and when enough zombie
threads have accumulated, it will no longer be possible to create new
threads (or processes).
Hi below is my coding snippet
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#define TIMEOUT 3
int threadFinished = 0;
pthread_mutex_t g_mutex;
void *threadFunction(void* attr)
{
pthread_mutex_lock(&g_mutex);
char *pData = (char*)attr;
if(pData)
{
printf("data from main thread is : %s\n",pData);
}
sleep(10);
threadFinished = 1;
pthread_mutex_unlock(&g_mutex);
return (void*)"This is thread message !";
}
int main()
{
pthread_t tid;
char *retVal = NULL;
int iTimeOut = TIMEOUT;
int i =0;
pthread_mutex_init(&g_mutex,NULL);
pthread_create(&tid,NULL,threadFunction,"Message from main thread");
//printf("itimeout %d , threadrunning %d\n",iTimeOut,threadRunning);
while(iTimeOut!=0 && !threadFinished)
{
printf("waiting %d\n",++i);
sleep(1);
iTimeOut--;
printf("changing the threadfinish varible\n");
//pthread_mutex_lock(&g_mutex); //statement 1
threadFinished = 1;
//pthread_mutex_unlock(&g_mutex); // statement 2
printf("changed the threadfinish varible\n");
}
if(iTimeOut==0)
{
if(!threadFinished)
{
printf("Timed out so cancelling the thread \n");
pthread_cancel(tid);
}
else
{
printf("thread finished \n");
}
}
else
{
printf("thread finished its job \n");
pthread_join(tid,(void*)&retVal);
}
pthread_mutex_destroy(&g_mutex);
threadFinished = 0;
printf("message from thread is : %s\n",retVal);
return 0;
}
When statement1 & statement2 are commented I am expecting child thread to change my testrunning variable first before main thread but it is working properly only when statement1 and statement2 are uncommented.
My question is why in child thread mutex lock is not locking my testrunning variable . it is allowing main thread to modify testrunning variable.
When accessing a variable concurrently from multiple threads, each thread needs to protect access to it via the same mutex. The main() thread fails to do so.
To correct this you could change main()'s while-loop like this:
while (iTimeOut != 0)
{
{
pthread_mutex_lock(&g_mutex);
int finished = threadFinished;
pthread_mutex_unlock(&g_mutex);
if (finished)
{
break;
}
}
printf("waiting %d\n",++i);
sleep(1);
iTimeOut--;
printf("changing the threadfinish varible\n");
pthread_mutex_lock(&g_mutex); //statement 1
threadFinished = 1;
pthread_mutex_unlock(&g_mutex); // statement 2
printf("changed the threadfinish varible\n");
}
Also you might like to consider narrowing locking to where it is necessary inside the thread-function like this:
void *threadFunction(void* attr)
{
char *pData = attr; /* No need to cast here in C, as opposed to C++. */
if(pData)
{
printf("data from main thread is : %s\n",pData);
}
sleep(10);
pthread_mutex_lock(&g_mutex);
threadFinished = 1;
pthread_mutex_unlock(&g_mutex);
return "This is thread message !"; /* No need to cast here in C, as opposed to C++. */
}
You should added error checking to all library calls in case a failure would influence the remaining execution.
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.