In my Advance OS work, I need to read data from file and assign it to threads for further processing..
this is my code to read data from file and pass it to thread function
int main() {
FILE *fp = fopen(fileName, "r");
char str_pass[80][MAX_CHAR];
if (fp == NULL){
printf("Could not open file");
return 1;
}
int i=0;
pthread_t thread[THREADS];
int rc;
for(int th=1; th<=THREADS; th++)
{
if(fgets(str_pass[i], MAX_CHAR, fp) != NULL){
//printf("Hello, Thread %d\n",i);
rc = pthread_create(&thread[i], NULL, create_thread, (void*)str_pass[i]);
pthread_join(thread[i],NULL);
if(rc)
{
printf("ERROR; return code from pthread_create() is %d\n",rc);
exit(-1);
}
pthread_join(thread[i],NULL);
i++;
}
else{
printf("End of File");
exit(0);
}
}
pthread_exit(NULL);
fclose(fp);
return 0;
}
and here is my thread code;
void * create_thread(void *hash_string)
{
gen_combinations(hash_string);
//sleep(1);
pthread_exit(NULL);
return NULL;
}
This code is working fine and it is creating threads as much as I define value in THREADS variable, until unless it does not find any record in file. But now I've to do it with thread pooling concept. Because I can't generate as many threads as data in file.
So I need to implement multi-threading using thread pooling. I did
some search on it but didn't get any clearance on it. And now I'm
totally stuck here and not getting any idea from where to start and
how to do this work???
Any kind of help will be appreciated.
Look up the "producer / consumer problem" if you are not already familiar with it, specifically the variation with multiple consumers. Your main thread plays the role of the producer, reading data and parameters from the input file, and packaging them into tidy units of work -- these are the widgets being produced. The worker threads play the role of the consumers, accepting units of work and "consuming" them, as it were, by actually performing the work described. That's a thread pool.
Your particular implementation probably does not need to be generic. It can be designed and tuned as appropriate to specifically serve the problem at hand.
rc = pthread_create(&thread[i], NULL, create_thread, (void*)str_pass[i]);
pthread_join(thread[i],NULL);
if(rc)
{
printf("ERROR; return code from pthread_create() is %d\n",rc);
exit(-1);
}
pthread_join(thread[i],NULL);
Two major bugs here:
You call pthread_join right after you create the thread. That means you wait for the thread to complete. What's the point of creating the thread then?
Once pthread_join returns, the thread no longer exists and its ID is now invalid. Yet you call pthread_join again and pass it the thing that was the ID before but is now junk. The consequences of doing this are entirely unpredictable.
In your example you only have one thread active at a time. You start it and wait till it ends up before reading the next line from the file. It is caused by the pthread_join which follows the thread creation. Instead you need to move the join statement outside of the loop to join all the threads you created.
Now, you can limit the number of thread without creating a pool. You just need an atomic counter which you would increment before the thread starts and decrement when the thread finishes. This way you can check the value of the counter before creating the next thread and wait on a conditional variable. This would be a kind of a semaphore.
Schematically something like the following:
counter = 0;
while {
lock counter;
while (counter > 8)
wait_on_conditional_variable
counter ++;
unlock counter;
run thread;
}
join all remaining threads.
in the thread
do work;
lock counter;
counter --;
signal cond var;
unlock counter;
return;
For the pool you would need to start several threads. Every thread has a loop where it waits for some job to be available. Most likely getting it from a fifo. It has to wait on a conditional variable to check.
thread
do {
lock fifo;
while (fifo.size == 0)
wait on conditional variable.
read job from fifo;
unlock fifo;
do work;
} while (!exiting);
while you reading the file, the following should be done
while ... {
lock fifo;
push line into fifo;
signal var;
unlock fifo;
}
set-exit-condition;
join the pools.
I hope this would help.
But there are multiple ways and optimizations which you could do there.
Related
poll() in main() waits for some sort of a trigger from another application and when there is a trigger, pollHandler() is executed. In pollHandler(), I want to start 'n' number of threads based on the number of requests in the poll message.
But now in pollHandler(), when I want to use pthread_join in a different for loop, I don't have access to the thread_ids. I could create an array of pthread ids and use it outside the for loop block accessible to both pthread_create and pthread_join but the poll() function is active and it could get called again and again, thus overwriting the thread ids. How do I keep things clean here - wait for each thread to finish and make room to have more threads?
int pollHandler(){
int num_req = poll.size();
for(int i=0; i < num_req; i++){
// start thread for each req
pthread_t tid;
// thread paramters dynamically allocated and freed later
struct parameters *p = (struct parameters*)malloc(sizeof(struct parameters));
if((pthread_create(&tid, NULL, thread_func, p) != 0){
return -1;
}
}
for(int i=0; i < num_req; i++){
// pthread_join here but no access to thread ids?
}
return 0;
}
int main(){
......
while(1){
poll(); //waits for a trigger from another application
}
}
I want to start 'n' number of threads based on the number of requests in the poll message.
This design is fundamentally flawed: if you get a request with (say) 10,000 requests, it is unlikely that you will be able to create a separate thread to handle each one, and even if you could, thread creation and destruction are inefficient and best avoided.
A much better design is to start a thread pool, and dispatch work to them, waiting for all work to be completed before returning, as Martin James suggested.
That said, here is correct (except error checking is omitted for clarity) way to implement your current design:
int pollHandler(){
int num_req = poll.size();
pthread_t *tids = calloc(num_req * sizeof(pthread_t));
for(int i=0; i < num_req; i++){
// start thread for each req
// thread paramters dynamically allocated and freed later
struct parameters *p = (struct parameters*)malloc(sizeof(struct parameters));
if((pthread_create(&tid[i], NULL, thread_func, p) != 0){
// bug here.
return -1;
}
}
for(int i=0; i < num_req; i++){
pthread_join(tids[i], NULL);
}
free(tids);
return 0;
I could create an array of pthread ids and use it outside the for loop block accessible to both pthread_create and pthread_join but the poll() function is active and it could get called again and again, thus overwriting the thread ids.
Unless pollHandler() can interrupt another pollHandler(), it will not be invoked until previous invocation finishes, so the code above is "safe".
If pollHandler() can run as part of an interrupt, then your code is already hopelessly broken (neither malloc, nor pthread_create are async-signal safe and thus can't be called in signal handler).
P.S. What's up with //bug here?
You can't just return there -- you need to join the threads you've already created. You would also need to free(tids); there as well.
I'm studying on condition variables of Pthread. When I'm reading the explanation of pthread_cond_signal, I see the following.
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).
Till now I knew pthread_cond_signal() would make only one thread to wake up at a time. But, the quoted explanation says at least one. What does it mean? Can it make more than one thread wake up? If yes, why is there pthread_cond_broadcast()?
En passant, I wish the following code taken from UNIX Systems Programming book of Robbins is also related to my question. Is there any reason the author's pthread_cond_broadcast() usage instead of pthread_cond_signal() in waitbarrier function? As a minor point, why is !berror checking needed too as a part of the predicate? When I try both of them by changing, I cannot see any difference.
/*
The program implements a thread-safe barrier by using condition variables. The limit
variable specifies how many threads must arrive at the barrier (execute the
waitbarrier) before the threads are released from the barrier.
The count variable specifies how many threads are currently waiting at the barrier.
Both variables are declared with the static attribute to force access through
initbarrier and waitbarrier. If successful, the initbarrier and waitbarrier
functions return 0. If unsuccessful, these functions return a nonzero error code.
*/
#include <errno.h>
#include <pthread.h>
#include <stdio.h>
static pthread_cond_t bcond = PTHREAD_COND_INITIALIZER;
static pthread_mutex_t bmutex = PTHREAD_MUTEX_INITIALIZER;
static int count = 0;
static int limit = 0;
int initbarrier(int n) { /* initialize the barrier to be size n */
int error;
if (error = pthread_mutex_lock(&bmutex)) /* couldn't lock, give up */
return error;
if (limit != 0) { /* barrier can only be initialized once */
pthread_mutex_unlock(&bmutex);
return EINVAL;
}
limit = n;
return pthread_mutex_unlock(&bmutex);
}
int waitbarrier(void) { /* wait at the barrier until all n threads arrive */
int berror = 0;
int error;
if (error = pthread_mutex_lock(&bmutex)) /* couldn't lock, give up */
return error;
if (limit <= 0) { /* make sure barrier initialized */
pthread_mutex_unlock(&bmutex);
return EINVAL;
}
count++;
while ((count < limit) && !berror)
berror = pthread_cond_wait(&bcond, &bmutex);
if (!berror) {
fprintf(stderr,"soner %d\n",
(int)pthread_self());
berror = pthread_cond_broadcast(&bcond); /* wake up everyone */
}
error = pthread_mutex_unlock(&bmutex);
if (berror)
return berror;
return error;
}
/* ARGSUSED */
static void *printthread(void *arg) {
fprintf(stderr,"This is the first print of thread %d\n",
(int)pthread_self());
waitbarrier();
fprintf(stderr,"This is the second print of thread %d\n",
(int)pthread_self());
return NULL;
}
int main(void) {
pthread_t t0,t1,t2;
if (initbarrier(3)) {
fprintf(stderr,"Error initilizing barrier\n");
return 1;
}
if (pthread_create(&t0,NULL,printthread,NULL))
fprintf(stderr,"Error creating thread 0.\n");
if (pthread_create(&t1,NULL,printthread,NULL))
fprintf(stderr,"Error creating thread 1.\n");
if (pthread_create(&t2,NULL,printthread,NULL))
fprintf(stderr,"Error creating thread 2.\n");
if (pthread_join(t0,NULL))
fprintf(stderr,"Error joining thread 0.\n");
if (pthread_join(t1,NULL))
fprintf(stderr,"Error joining thread 1.\n");
if (pthread_join(t2,NULL))
fprintf(stderr,"Error joining thread 2.\n");
fprintf(stderr,"All threads complete.\n");
return 0;
}
Due to spurious wake-ups pthread_cond_signal could wake up more than one thread.
Look for word "spurious" in pthread_cond_wait.c from glibc.
In waitbarrier it must wake up all threads when they all have arrived to that point, hence it uses pthread_cond_broadcast.
Can [pthread_cond_signal()] make more than one thread wake up?
That's not guaranteed. On some operating system, on some hardware platform, under some circumstances it could wake more than one thread. It is allowed to wake more than one thread because that gives the implementer more freedom to make it work in the most efficient way possible for any given hardware and OS.
It must wake at least one waiting thread, because otherwise, what would be the point of calling it?
But, if your applicaton needs a signal that is guaranteed to wake all of the waiting threads, then that is what pthread_cond_broadcast() is for.
Making efficient use of a multi-processor system is hard. https://www.e-reading.club/bookreader.php/134637/Herlihy,Shavit-_The_art_of_multiprocessor_programming.pdf
Most programming language and library standards allow similar freedoms in the behavior of multi-threaded programs, for the same reason: To allow programs to achieve high performance on a variety of different platforms.
I am working on a project with a user defined number of threads I am using 7 at the moment. I have a while loop that runs in each thread but I need all of the threads to wait for each other at the end of the while loop. The tricky thing is that some of the threads do not all end on the same number of times through the loop.
void *entryFunc(void *param)
{
int *i = (int *)param;
int nextPrime;
int p = latestPrime;
while(latestPrime < testLim)
{
sem_wait(&sem);
nextPrime = findNextPrime(latestPrime);
if(nextPrime != -1)
{
latestPrime = nextPrime;
p = latestPrime;
}
else
{
sem_post(&sem);
break;
}
sem_post(&sem);
if(p < 46341)
{
incrementNotPrimes(p);
}
/*
sem_wait(&sem2);
doneCount++;
sem_post(&sem2);
while(go != 1);
sem_wait(&sem2);
doneCount--;
//sem_post(&sem3);
sem_post(&sem2);
*/
}
return NULL;
}
where the chunk of code is commented out is part of my last attempt at solving this problem. That is where the functions all need to wait for each other. I have a feeling I am missing something simple.
If your problem is that on each thread, the while loop has a different numbers of iterations and some threads never reach the synchronization point after exiting the loop, you could use a barrier. Check here for an example.
However you need to decrease the number of threads at the barrier after you exit each thread. Waiting at the barrier will end after count number of threads reached that point.
So you need to update the barrier object each time a thread finishes. And make sure you do this atomically.
As I mentioned in the comments, you should use a barrier instead of a semaphore for this kind of situation, as it should be simpler to implement (barriers have been designed exactly to solve that problem). However, you may still use a semaphore with a little bit of arithmetic
arithmetic: your goal is to have all thread execute the same code path, but somehow the last thread to finish its task should wake all the other threads up. One way to achieve that is to have at the end of the function an atomic counter which each thread would decrement, and if the counter reaches 0, the thread simply calls as many time sem_post as necessary to release all the waiting threads, instead of issuing a sem_wait as the others.
A second method, this time using only a semaphore, is also possible. Since we cannot differentiate the last thread for the others, all the threads must do the same operations with the semaphore, ie try to release everyone, but also wait for the last one. So the idea is to initialize the semaphore to (1-n)*(n+1), so that each of the n-1 first threads would fail at waking up their friends with n+1 calls to sem_post, but still work toward getting the semaphore at exactly 0. Then the last thread would do the same, pushing the semaphore value to n+1, thus releasing the locked threads, and leaving room for it to also perform its sem_wait and be released immediately.
void *entryFunc(void *param)
{
int *i = (int *)param;
int nextPrime;
int p = latestPrime, j;
while(latestPrime < testLim){
nextPrime = findNextPrime(latestPrime);
if(nextPrime != -1)
{
latestPrime = nextPrime;
p = latestPrime;
}
if(p < 46341)
{
incrementNotPrimes(p);
}
}
for (j=0;j<=THREAD_COUNT;j++)
sem_post(&sem);
sem_wait(&sem);
return NULL;
}
The problem with this approach is that it doesn't deal with how the semaphore should be reset in between uses (if your program needs to repeat this mechanism, it will need to reset the semaphore value, since it will end up being 1 after this code has been executed successfully).
I seem to be running in to a possible deadlock with a pthreads conditional variable.
Here is the code
thread function(){
for (condition){
do work
/* should the thread continue? */
if (exit == 1){
break; /* exit for */
}
} /* end for */
pthread_mutex_lock(&mtxExit);
exit = 0;
pthread_cond_signal(&condVar);
pthread_mutex_unlock(&mtxExit);
}
The main function is as follows:
function main(){
if (thread is still active){
pthread_mutex_lock(&mtxExit);
exit = 1;
pthread_mutex_unlock(&mtxExit);
} /* end if */
while (exit == 1){
pthread_mutex_lock(&mtxExit);
/* check again */
if (exit == 1)
pthread_cond_wait(&condVar, &mtxExit);
pthread_mutex_unlock(&mtxExit);
}
create new thread()
....
}
The code is always getting stuck at cond_wait. :(
EDIT:
Let me add some clarification to the thread to explain what I am doing.
At any given time, I need only one thread running. I have a function that starts the thread, tells it what to do and the main thread continues it work.
The next time the main thread decides it needs to spawn another thread, it has to make sure the thread that was previously started has exited. I cannot have two threads alive at the same time as they will interfere with each other. This is by design and by definition of the problem I am working on.
That is where I am running in to problems.
This is my approach:
Start the thread, let it do its job.
the thread checks in every step of its job to see if it is still relevant. This is where "exit" comes in to picture. The main thread sets "exit" to 1, if it needs to tell the thread that it is no longer relevant.
In most cases, the thread will exit before the main thread decides to spawn another thread. But I still need to factor in the case that the thread is still alive by the time the main thread is ready to start another one.
So the main thread sets the value of "exit" and needs to wait for the thread to exit. I dont want to use pthread_kill with 0 as signal because then main thread will be in a loop wasting CPU cycles. I need the main thread to relinquish control and sleep/wait till the thread exits.
Since I only need one thread at a time, I dont need to worry about scaling to more threads. The solution will never have more than one thread. I just need a reliable mechanism to test if my thread is still alive, if it is, signal it to exit, wait for it to exit and start the next one.
From my testing, it looks like, the main thread is still entering the conditional variable even if the thread may have exited or that the signal is not getting delivered to the main thread at all. And its waiting there forever. And is some cases, in debugger I see that the value of exit is set to 0 and still the main thread is waiting at signal. There seems to be a race condition some where.
I am not a fan of how I set up the code right now, its too messy. Its only a proof of concept right now, I will move to a better solution soon. My challenge is to reliably signal the thread to exit, wait on it to exit.
I appreciate your time.
Did you forget to initialize your condition variable?
pthread_cond_init(&condVar, NULL)
while (exit == 1) {
In the code you quote, the way you quote I do not see any particular problem. It is not clean, but it appears functional. What leads me to believe that somewhere else you are setting exit to 0 without signaling that. Or the thread is getting stuck somewhere doing the work.
But considering the comments which hint that you try to signal one thread to terminate before starting another thread, I think you are doing it wrong. Generally pthread condition signaling shouldn't be relied upon if a signal may not be missed. Though it seems that state variable exit covers that, it is still IMO wrong application of the pthread conditions.
In the case you can try to use a semaphores. While terminating, the thread increments the termination semaphore so that main can wait (decrement) the semaphore.
thread function()
{
for (condition)
{
do work
/* should the thread continue? */
if (exit == 1) {
break; /* exit for */
}
} /* end for */
sem_post(&termSema);
}
function main()
{
if (thread is still active)
{
exit = 1;
sem_wait(&termSema);
exit = 0;
}
create new thread()
....
}
As a general remark, I can suggest to look for some thread pool implementations. Because using a state variable to sync threads is still wrong and doesn't scale to more than one thread. And error prone.
When the code is stuck in pthread_cond_wait, is exit 1 or 0? If exit is 1, it should be stuck.
If exit is 0, one of two things are most likely the case:
1) Some code set exit to 0 but didn't signal the condition variable.
2) Some thread blocked on pthread_cond_wait, consumed a signal, but didn't do whatever it is you needed done.
You have all sorts of timing problems with your current implementation (hence the problems).
To ensure that the thread has finished (and its resources have been released), you should call pthread_join().
There is no need for a pthread_cond_t here.
It might also make more sense to use pthread_cancel() to notify the thread that it is no longer required, rather than a flag like you are currently doing.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void *thread_func(void *arg) {
int i;
for (i = 0; i < 10; i++) {
/* protect any regions that must not be cancelled... */
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
/* very important work */
printf("%d\n", i);
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
/* force a check to see if we're finished */
pthread_testcancel();
/* sleep (for clarity in the example) */
sleep(1);
}
return NULL;
}
void main(void) {
int ret;
pthread_t tid;
ret = pthread_create(&tid, NULL, thread_func, NULL);
if (ret != 0) {
printf("pthread_create() failed %d\n", ret);
exit(1);
}
sleep(5);
ret = pthread_cancel(tid);
if (ret != 0) {
printf("pthread_cancel() failed %d\n", ret);
exit(1);
}
ret = pthread_join(tid, NULL);
if (ret != 0) {
printf("pthread_join() failed %d\n", ret);
exit(1);
}
printf("finished...\n");
}
It's also worth noting:
exit() is a library function - you should not declare anything with the same name as something else.
Depending on your specific situation, it might make sense to keep a single thread alive always, and provide it with jobs to do, rather than creating / cancelling threads continuously (research 'thread pools')
I have an assignment in class that requires us to use POSIX threads and create n*(n-1)/2 of them to process a dataset of n elements.
You can think of it as basically the classical "handshake" in probability.
I know that for a large data set it's going to make the application CPU-bound and eventually it will spend so much time context switching that it will be useless, but the assignment requires us to do this.
However, my loop to create all the threads ceases creating them after a while.
For the code below, I will see output like:
making thread
thread start
thread done
made thread 1944
making thread
thread start
thread done
made thread 1945
making thread
thread start
thread done
made thread 1946
making thread
for a while, but then I will stop seeing the "thread start" and "thread done" messages, and only see the "making thread, made thread" messages.
Here is the loop that creates the threads:
int tCtr = 0;
tArr = (pthread_t*)malloc(((numbers_read) * (numbers_read - 1)/2) * sizeof(pthread_t));
for(i=0; i<numbers_read; i++){
int j;
for(j=i; j<numbers_read; j++){
// n(n-1)/2
if(i != j){
printf("making thread\n");
struct comparison_struct *data;
data = (struct comparison_struct *)malloc(sizeof(struct comparison_struct));
data->i_value = &numbers[i];
data->j_value = &numbers[j];
data->i_arr_entry = &wArr[i];
data->j_arr_entry = &wArr[j];
pthread_create(&tArr[tCtr], NULL, compare_thread, (void *)data);
printf("made thread %d\n", tCtr);
tCtr++;
}
}
}
for(i=0; i<tCtr; i++){
pthread_join(tArr[i], NULL);
}
free(tArr);
and here is the subroutine containing the thread code:
void *compare_thread(void *vData) {
printf("thread start\n");
struct comparison_struct *data;
data = (struct comparison_struct *)vData;
if(*data->i_value <= *data->j_value){
*data->i_arr_entry = 0;
} else {
*data->j_arr_entry = 0;
}
free(vData);
printf("thread done\n");
return NULL;
}
Anybody have any ideas? I'm new to pthreads and having trouble figuring it out.
I know that if I put the pthread_join call immediately after the pthread_create, the application works - but then it blocks on every thread, which I'd assume would decrease performance because there will only ever actually be 2 threads running at a time.
check the return value of pthread_create, maybe you are hitting a resource limit.
pthread_create() will fail if:
[EAGAIN] The system lacked the necessary resources to create
another thread, or the system-imposed limit on the
total number of threads in a process
[PTHREAD_THREADS_MAX] would be exceeded.
[EINVAL] The value specified by attr is invalid.
If you are reaching a resource limit, you can try to make a thread that joins on the other threads, make a worker queue and give work to each of the threads via the queue, or if you control the resource limit of the system try to increase it.
if I put the pthread_join call immediately after the pthread_create ...then it blocks on every thread...there will only ever actually be 2 threads running at a time.
An alternative to joining the threads is to just create them as detached. Create and initialize a pthread_attr_t, set it detached and pass the attr in with your pthread_create call.
pthread_attr_t attr;
int ret;
ret = pthread_attr_init(&attr);
if (ret)
// error .........
ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
for (....)
{
//........
ret = pthread_create(&tArr[tCtr], &attr, compare_thread, (void *)data);
//.......
}
ret = pthread_attr_destroy(&attr);
There is also no requirement that a thread that creates another thread has to be the one to join it. You can create a thread just to join all other created threads. But that is probably going beyond the call of duty for this assignment.