PDA

View Full Version : Pthreaded server



tezcatlipooca
11-29-2007, 06:12 AM
Hello,

I am making a threaded server using pthreads.
Whenever server accepts a new connection, a new thread is created to handle client's requests.

Now i am thinking that as server's listening queue max length is defined at compilation time, i could use a static array of the same size to store thread's ids..

My problem is how to find out that a thread has returned, so I can pass it's id to a new thread. Is there a function or something to check threads state? Or maybe I should check the return value of each pthread_create()?

May someone help me please?

PS: I 've thought of pthread_join but I rejected the idea because that would make the parent thread to block, while i want it to always run to accept new connections.

matsp
11-29-2007, 06:16 AM
I like the idea of letting each thread be responsible to "mark itself free" when it's finished. Whether you then let the thread kill itself, the main thread kills it, or it just waits for another new connection [or a combination thereof, e.g. wait for 2 minutes for a connection, then shut itself down].

The idea is that the thread itself is best at knowing what's going on with it's processing, so it can deal with whatever situations that it deems is "finished", rather than trying to get that information back into the master thread by interrogating the thread.

--
Mats

tezcatlipooca
11-29-2007, 06:49 AM
I sense that it would be rather risky for a thread to mark itself free and then kill itself because it may blocks after marking itself (assuming that scheduler acts randomly) and then main thread would suppose that a running thread has exited

On the other hand, i find it more reliable for the parent process to kill the thread (using pthread_cancel right?) after the thread has marked itself as free.

But what if parent thread tries to kill a thread which has already exited?

PS:I guess i can use a dynamic structure to store thread ids instead of static one; I just sense that the second one will be more efficient.

matsp
11-29-2007, 07:06 AM
I sense that it would be rather risky for a thread to mark itself free and then kill itself because it may blocks after marking itself (assuming that scheduler acts randomly) and then main thread would suppose that a running thread has exited

On the other hand, i find it more reliable for the parent process to kill the thread (using pthread_cancel right?) after the thread has marked itself as free.

But what if parent thread tries to kill a thread which has already exited?

PS:I guess i can use a dynamic structure to store thread ids instead of static one; I just sense that the second one will be more efficient.

If you have a static array or say a linked list will probably make VERY little difference, compared to the time it takes to for example create a new thread.

But of course, you still need a way to know when the thread is "dead" so that you can clear out any leftover stuff in your list/array. If the thread kills itself, and then main creates a replacement, that should work - even if it's not completely killled - as long as it's not holding any resources that the new thread needs.

--
Mats

brewbuck
11-29-2007, 12:06 PM
I sense that it would be rather risky for a thread to mark itself free and then kill itself because it may blocks after marking itself (assuming that scheduler acts randomly) and then main thread would suppose that a running thread has exited

On the other hand, i find it more reliable for the parent process to kill the thread (using pthread_cancel right?) after the thread has marked itself as free.

But what if parent thread tries to kill a thread which has already exited?

PS:I guess i can use a dynamic structure to store thread ids instead of static one; I just sense that the second one will be more efficient.

You make good observations but miss the inherent solution: pthread_join(). I know you don't want to use it because it is synchronous, but it's the only way to detect thread termination in a race-free way. Because it is unsuitable for your purpose here, this should lead you to think that your whole approach is wrong. Sorry to say...

Why do you want to keep an array of thread handles, anyway? Instead of maintaining this array, why not just keep a counter of how many active threads there are, and never exceed some fixed limit? I.e.



/* Called by the main thread to spawn workers */
void spawn_worker_thread()
{
pthread_mutex_lock(&worker_count_lock);
while(worker_count >= max_worker_count)
{
pthread_cond_wait(&worker_count_cond, &worker_count_lock);
}
worker_count++;
pthread_mutex_unlock(&worker_count_lock);
launch_new_thread();
}

/* Called by a worker thread right before it dies */
void worker_thread_dying()
{
pthread_mutex_lock(&worker_count_lock);
worker_count--;
pthread_cond_broadcast(&worker_count_cond);
pthread_mutex_unlock(&worker_count_lock);
}


The worker count decreases before the dying worker actually goes away, but that's okay, if worker_thread_dying() really is the very last thing which happens before worker thread death.

tezcatlipooca
11-29-2007, 12:22 PM
Well, the point is that it is essential to keep the threads' ids for further manipulation.
On the other hand the number of total threads running is bounded by the listening queue 's length (as a new thread is created only after parent accept()s) so i don't actually need an explicit counter.


The worker count decreases before the dying worker actually goes away, but that's okay, if worker_thread_dying() really is the very last thing which happens before worker thread death.

That's the idea of my implementation, a child thread marks itself free and then terminates.

brewbuck
11-29-2007, 01:10 PM
Well, the point is that it is essential to keep the threads' ids for further manipulation.

What the heck are you "manipulating" them for?