[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-core-devel
Subject:    Re: threads
From:       Lubos Lunak <l.lunak () sh ! cvut ! cz>
Date:       1999-12-04 11:50:25
[Download RAW message or body]

On Pá, 03 pro 1999, Waldo Bastian wrote :
>> Summary:
>> ========
>> 
>> Its basically impossible to get pre-emptive multithreading reliable.

I disagree. It is possible, you just have to be skilled and experienced
enough to write the code correctly.

>> 
>> Cooperative multithreading is an option. The benefit is that it is much 
>> easier to program a worker thread than QTimer beased state machine. The 
>> disadvanatge is that calls like fopen() still block. 
>> 
>> The other option is to use processes as we do with the io_slaves. The 
>> disadvantage here is that it requires more memory and the IPC is somewhat 
>> slower. The advantage is that a dying io_slave doen't crash your application.
>> 
>> 
>> Discussion:
>> =========
>> 
>> In theory you can do cooperative multithreading toghether with 
>> kernel-threads.  Whenever you are about to enter a possible-blocking system 
>> call, you use a kernel-thread for this. This way you can make it that you 
>> keep the semantics of cooperative-multithreading but you don't have the 
>> disadvantage of blocking on system calls.
>> 
>> (A quick & dirty way to get this behaviour is to use kernel-threads and lock 
>> a mutex all the time except for when you are about to enter a system call.)
>
>Following up on myself:
>
>A quick investigation of some Threading-FAQs seems to indicate that there is no
>"portable non-preemptive non-blocking threads library". 
>
>* Pth is portable an non-preemptive but can block.
>* pthreads is portable and non-blocking but is preemptive.
>* It might be possible to get non-preemptive non-blocking behaviour on 
>commerical Unices by specifying some smart thread-priorities but this is not 
>portable and possibly not save on multi-processor systems.

 Cooperative threading library coming with its own replacement for libc is
non-preemptive and non-blocking. I don't how about portability. Example of this
is Solaris ( it is basically cooperative, e.g. endless loop can block all
other threads ). Another example are pmpthreads ( AKA Provenzano threads ),
AFAIK no longer being developed.
 But blocking maybe is not that big problem as it seems to be. You can code
many things with just Pth's low-level blocking calls replacement. Many other
calls don't usually block for too long. If Pth could come with
portable replacement for few libc functions ( which is IMHO almost impossible ),
I think that would be enough for almost all cases.
 Also, it's actually impossible to have cooperative threads which don't block
at all. You can for example have a library which does some time expensive
matrix operations - it doesn't call any system calls, it just loop for too
long, and there is no yield() in it. You'd have to modify it and recompile.
 And moreover, having non-blocking calls would also require all libraries that
can call them either to be reentrant or to be protected by a mutex( es ).

>
>What else can we do: Crippled POSIX threads.
>======================================
>
>We could use pthreads and cripple it to get non-preemptive behaviour. We lock a 
>mutex and only when we explicitly want to allow concurrency we unlock the 
>mutex. 
>
>* This means that whenever Qt goes to sleep on it's select() to wait for an 
>event, it should unlock the mutex and lock it again when it wakes up from the 
>select.
>
>* Threads can unlock the mutex whenever they are going to do some dangerous 
>(read: possibly blocking) system calls / library call and lock it again when 
>they return.
>

So you mean something like 
void yield()
{ pthread_unlock( &global_mutex );
  sleep( 0 ); // or sched_yield(), or whatever
  pthread_lock( &global_mutex );
}
and a pair of enter/leave_maybe_blocking_block() which just unlock/lock the
mutex ? Hey, I like it. This really seems to change preemptive threads to
cooperative ! But there are still two problems with it : The first one is, that
every maybe_blocking_block would have to be thread-safe and moreover take care
it doesn't break all the other parts which assume everything is cooperative.
 The second one is more important : Which working preemptive pthreads do you
want to cripple on let's say libc5 based Linux ? I actually don't how many
platforms are there which don't have pthreads at all or maybe have pthreads but
don't have very good thread-safe libc. For platforms with no pthreads at all,
this would be a showstopper. For platforms with thread-unsafe libc, all those
maybe_blocking_blocks would become pretty complicated, because even just
calling select() could break things. If all these platforms are unimportant,
this could be the way to go.

>I guess that the Troll's don't want to make Qt dependant on threads, so for 
>this to work, QApplication should call a virtual function whenever it is
>about to call select and call another virtual function after select has
>returned.

It's much easier to have QTimer with 0 timeout, which takes care of the
necessary things ( it can either poll with short sleeps or even actually do the
select() call, it doesn't matter ).

>
>Cheers,
>Waldo

 Anyway, since the file dialog now doesn't seem to need the threads, and none
of the threads solutions available now seems to be good enough for use in KDE,
and most people are simply afraid of threads, I think this threads discussion
will die as all the previous ones did.

 Lubos Lunak
 l.lunak@email.cz http://dforce.sh.cvut.cz/~seli

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic