[uClinux-dev] Threading and synchronization questions

Jamie Lokier jamie at shareable.org
Sat Feb 28 15:01:04 EST 2009

Jan Ringoš wrote:
> 1) If properly synchronized I can access data of other processes.

Yes, but only if you don't use certain GCC compile options (-fPIC etc.)

> 2) Is atomic write to a pipes up to PIPE_BUF guaranteed on uClinux?

Yes.  See "man pipe".

> 3) There is no practical distinction between process and thread in uClinux 
> as there is in Windows world.

Yes there is.  uClinux behaves the same as ordinary Linux.  There are
processes, and inside each process there can be multiple threads.

> 4) Can pthread mutexes be used across vfork/exec sub-processes?

No.  It won't work.  It might _look_ like it works - because it can
access memory in a different process without checking - but the
synchronisation won't be reliable.

Linux's pthread knows the difference between threads and processes.
In each process, it keeps a list of threads for that process, and
mutexes use that list.

> In documentation to pthreads they say that the pthread_mutex can be used to 
> synchronize threads but not processes. But I see no difference between 
> thread and process in uClinux. What am I missing?

Threads and processes are quite different.

> 5) There is no dynamicaly-loaded-library (DLL, or .so, or whatever) support.

The Linux name is DSO (dynamic shared object).  Yet another name :-)

It depends on the architecture.  Some uClinux architectures have them.

ARM no-MMU doesn't, but I have done some work on ARM FDPIC-ELF to add
support for DSOs.

> 6) Vfork does not copy any data/code from the old process to the new one, 
> or does it? The real question is, will some pointer carried to the new 
> process always point to a data in the old process.

You should be careful with vfork.  It's best avoided because it's
difficult to use safely, but on uClinux you don't have a choice.

Only do a few necessary things which are basic system calls, such as
call dup/dup2/close/chdir, then call execve or _exit.  Don't call
functions like printf or malloc, or exit.

In the vfork child process, you can access the parent's data but you
should not write to it.  This includes local variables in the function
which calls vfork which the parent might use after!  To be safe, you
can just call another function: if ((pid = vfork()) == 0)
child_function(); and never return from child_function, call _exit().

There are many other rules about safe vfork usage.  Keep it simple.

> 7) For data variety, I decided to use a SQLite database. In my current 
> design, there will be more separate processes running and using the 
> database. But the footprint of the SQLite is relatively large. Provided 
> that my code will comply to the threading limitations documented by SQLite, 
> can I have it loaded just in single core process, and accessed by other 
> processes? SQLite uses pthreads for synchronization.

SQLite is a good library.  But doing that isn't safe.  See above:
pthread mutexes won't synchronise reliably.

It's better to rely on SQLite's normal method of file locking, and
loading the library into separate processes.

> 8) If pthread_mutex cannot be used across processes, is there an 
> alternative?

You can use SYSV semaphores ("man semget"), and you can use sockets
and pipes with a protocol of course.  You can also use file locking:
fcntl(F_SETLKW).  SQLite uses file locking.

POSIX semaphores ("man sem_overview") are not available between
processes on Linux 2.4.  On Linux 2.6, they're not available on ARM
no-MMU yet because of the threading library.  (And *if* you had
working POSIX semaphores, you could create special process-wide
pthread mutexes too.)

> 9) Or is my approach of multiple processes otherwise flawed? My intension 
> is to minimize memory and disk footprint by including only components 
> necessary for particular application. Have I other option than to write big 
> monolithic process?

Sometimes you can reduce the footprint using XIP to share code of an
executable in multiple processes.  This can make a lot of difference
if you have, say, many Busybox processes running different commands.

The best way to reduce footprint (without a monolithic process) is
shared libraries, and that's not available on ARM no-MMU yet.  I have
done some work on it (ARM FDPIC), but it's stopped for now.

-- Jamie

More information about the uClinux-dev mailing list