0

i am programming a concurrent (multi-threaded) server application - using pthread, of cource!- when i encountered a problem with pthread_join, my app is shuch (pseudo-code):

/* Sheduler thread */
while (1) {

   c = get_client();
   r = get_resource();

   communication.c = c;
   communication.r = r;

   pthread_create( clnt_tid, null, clnt_fn, communication);
   resource_alloc_list_add(clnt_tid, r);

}

/* resources Collector thread */
while(!rs_alloc_list_is_empty()) {

   e = get_elt(rs_alloc);
   pthread_join(e.clnt_tid, retour);
   free_rs(e.r);
}
.........

the problem is that there is no non-bloquing pthread_join call - there is one but it isn't portable - and pthread_join can't join any thread like wait() in process programming . So if the rsc_collector thread is waiting for one client thread to exit to get back the allocated resource ,and before this happens all other threads have exited then their resource will be blocked - and the scheduler thread can't serve other client - until the first thread terminates his work . can you tell-me a possible solution to this problem ?

EDIT :

I'll be more specific , i am programming an local resource management system (lrms), or Remote Program execution system, there is three different programs : client pg, server pg, and scheduler pg, the client contact the scheduler and wait for scheduler pg to allocate him an idle server so he can after submit, execute his job on an remote server.the sched pg will en-queue the client address in the clients queue. in the other side , a server pg send an registration message to scheduler and wait for job, the scheduler enqueue the server address in the resources queue (so i mean by resource an remote server not resources allocated to the thread by system ). the scheduler pg consists of three principal threads :

  • main_thread : listing on socket binded at Well Known Port. receives and en-queue demands and registrations (In other word the Producer)
  • scheduler_thread : the consumer , de-queue cliets address get server (dequeue an server address), create the client thread ,save the client/server allocation. and loop on.
  • resource_collector thread : wait for clients threads to terminates to get back the allocated resource. i emphasize [*] to create a specific thread for resource collecting because it is very important for the proper fonctionnement of the system.

Note :

  • the client thread get an copy of the resource (server) not the original.
  • [*] if i eliminate that thread , and let each client free its esource (remote server address) so in some cases when an client thread crashes before the call to the free function , then the resource will be lost for ever ... that's why i wouldn't risk letting the resources under the full control of the clients threads.
DevDz
  • 3
  • 3
  • 2
    How can a client thread crash...without crashing your program...unless you are catching that crash...in which case you can free the resource? Does pthread_cleanup_push/pop apply? – johnnycrash Apr 14 '11 at 00:04
  • first I apologize for the delay.Second, yes, pthread_cleanup_push/pop applies ,but i was looking for another solution with out using pthread_cleanup_push/pop maybe using an flags array is the best solution . **Thanks a lot @johnnycrash** – DevDz Apr 21 '11 at 03:41

2 Answers2

0

I would recommend to do the necessary cleanup in exiting threads, not in a special collector thread. Specifically, thread-local data created with pthread_key_create() may have an associated destructor call invoked when a thread exits. This destructor could release the application resource(s) associated with the thread; the easiest way is to store a pointer to the resource(s) in the thread-specific slot (see pthread_set_specific()) in which case the pointer will be automatically sent to the destructor. The collector thread can still call pthread_join() if threads are created and destroyed all the time; though alternatively you can create the thread in detached state, or call pthread_detach() after creation.

Also look at a similar question asked earlier.

Community
  • 1
  • 1
Alexey Kukanov
  • 12,479
  • 2
  • 36
  • 55
  • Using Static pool of client threads needs some statistical study ... How many thread i'll create ? the system supports that number of threads ? the number of -client- threads must be more then the available servers (resources) ? .... – DevDz Apr 13 '11 at 22:52
0

As alexey previously said, the thread function can allocate and free its resources. You can also use pthread_cleanup_push and pop if you want a method that can handle cancelation.

You can use a global flag that tells you if a thread is still active or not. Set it to 1 before creating the thread and back to 0 when the thread function exits. If you have lots of threads, use an array. Simply test the variable to see if the thread is done.

Hopefully your collector thread doesn't continuously spin, which would consume resources.

Creating threads is slow. You probably want to keep a handful of threads around permanently and let them pick work to do from a queue. When there is no work, they should wait for a signal. When work is added to the queue you could signal as many threads as you wanted to wake up and start working again. this is 1000x faster than creating a thread for each piece of work and destroying the thread when the work is done.

johnnycrash
  • 5,184
  • 5
  • 34
  • 58
  • So why can't you detach the threads and periodically check a global as I describe above? You don't use pthread_join at all. – johnnycrash Apr 14 '11 at 00:03