> Which is more efficient in terms of speed,performance,resource usage, etc?
Which is more efficient, an apple or an orange? They are different things.
> My understanding is that a process involves a implicit fork/exec and all that
> it entails. What does a thread involve?
A thread create, which typically allocates a task control block of some
kind.
> When would one use a multi-threaded program as opposed to a simple fork/exec
>paradigm?
There is a Rob Pike quote somewhere which says something like 'If people
understood fork, they wouldn't have invented treads'. A multithreaded
program runs as one process, rather than a set of cooperating processes
started by 'fork'. The current favorite example is a WWW server, you have
a single process which is multithreaded to handle all the incoming
requests, rather than forking a process for each one.
> Does one method have some advantages that the other does not i.e. what are
>the pros and cons of each approach?
Typically it is more difficult to program a multithreaded program, you have
to worry about lots of things that the operating system takes care of under
the 'process' model, like not having deadlocks.
You might like to think of it as 'processes are threads to the kernel'.
Vikas> I am still having trouble understanding the following:
Vikas> If threads are simply flow-of-control blocks which executes
Vikas> within a given process, how are they any different (at the
Vikas> high-level language level) from a subroutine which is most
Vikas> always implemented as a 'function call' in C?
They execute in parallel.
Vikas> The only reason I can think of is that a thread_create
Vikas> implicitly binds the function that the thread_create points to
Vikas> a different CPU i.e. all new threads created are allocated to
Vikas> different CPUs as far as possible.
This is not always a win, depending on the underlying architecture
and how memory caching is handled.
Vikas> In contrast, all the function calls within a single process
Vikas> will necessarily be bound to the same CPU since after all, it
Vikas> is the same process, right?
The process may well migrate between CPUs when it is rescheduled.
Vikas> So, essentially, a multi-threaded program is useless on a
Vikas> single CPU machine, right?
Wrong.
Consider the HTTP server again. When a new connection arrives, the
required processing basically consists of:
- read the request (and possibly an input document)
- perform the requested action
- return the result and any output document
During any of these stages, it may be necessary to wait for some event,
such as more data arriving, or output buffer space on the socket, or
completion of a disk access, whatever. In a single-threaded program
this is hard to handle efficiently; you end up having to write the
request-processing code such that it represents its internal state
as data rather than in the program flow. In a multi-threaded or
multi-process implementation, on the other hand, the code is simple,
and when one thread/process is blocked waiting for something, the CPU
is available for use by other threads or processes.
Remember that in a "non-threaded" system, you still actually have
threads, exactly one thread per process. Having multiple threads on
a single CPU is useful in the same ways as having multiple processes
on a single CPU.
Vikas> I am just trying to understand what the big deal about threads
Vikas> is in terms of providing parallel execution of tasks i.e. what
Vikas> exactly justifies taking all that additional coding effort
Vikas> (mutex, semaphores, locking/deadlocking problems, etc) ?
Because it is less effort than the alternatives, or more efficient.
--
Andrew.
comp.unix.programmer FAQ: see <URL: http://www.erlenstar.demon.co.uk/unix/>
>> Threads ... They execute in parallel.
Vikas> Umm.. maybe I need to go back to Unix textbooks but doesnt a
Vikas> CPU run one and only ONE process AT A TIME i.e. in a given
Vikas> time-slice, Unix kernel loads only one process image. So if
Vikas> this process now splits off into 10 threads, how can all of
Vikas> them run *simultaneously* on that same CPU under that same
Vikas> process image? At a given instant in time, what *exactly* is
Vikas> the CPU running? All the threads? How come?
Threads are scheduled like processes.
One of the advantages of threads (on some systems) is that since there
is less context associated with a thread, switching context between
threads is cheaper than for processes, since the address space is not
changed. (Changing the address space requires flushing the TLB and
possibly also the caches, so the incoming process takes a lot of TLB
misses and cache misses.)
>> During any of these stages, it may be necessary to wait for some event,
>> such as more data arriving, or output buffer space on the socket, or
>> completion of a disk access, whatever. In a single-threaded program
>> this is hard to handle efficiently; you end up having to write the
>> request-processing code such that it represents its internal state
>> as data rather than in the program flow. In a multi-threaded or
>> multi-process implementation, on the other hand, the code is simple,
>> and when one thread/process is blocked waiting for something, the CPU
>> is available for use by other threads or processes.
Vikas> Arent you using threads and processes in an interchangeable
Vikas> fashion here? One of my questions in my initial posting was
Vikas> exactly this i.e. can threads and processes be used
Vikas> interchangeably and the answer was a resounding NO.
Um, what I said was:
---
Vikas> Can they be used interchangeably?
No. They are different tools; some jobs can be performed by either,
but some jobs can be done better with one or the other.
---
Most common examples of threads use *could* be implemented with
processes instead. HTTP serving is implementable either way.
However, they aren't interchangeable in the sense that while
a given objective can be achieved with either, it will generally
require design changes.
Vikas> In the scenario you describe above, cant each step in the
Vikas> processes be performed by a fork()ed process? Before you
Vikas> hasten to chastize me, I agree that forking would be a more
Vikas> expensive solution in the above situation, but it is
Vikas> *possible*, right? That would eliminate the 'wait for I/O' or
Vikas> 'wait for XXX' problem.
Exactly.
Vikas> So basically, a thread is simply a light-weight, less resource
Vikas> intensive variant of a process in that it eliminates the
Vikas> costly forking/context-switching, etc, right?
Right. But a lightweight context switch isn't always a win (consider
the FTP server example).
Vikas> Parallel execution is not the point really since both threads
Vikas> and processes can run in parallel (or can they? see my first
Vikas> question above)
The additional complexities of thread programming arise from the fact
that you're doing concurrency within a single address space. Process
isolation makes things much easier, in some respects.
>> Remember that in a "non-threaded" system, you still actually have
>> threads, exactly one thread per process. Having multiple threads on
>> a single CPU is useful in the same ways as having multiple processes
>> on a single CPU.
Vikas> Err.. you mean 'having multiple processes on multiple CPUs'
Vikas> dont you?
No. I meant what I said.
Vikas> Thanks for your continued help. Am I getting close or still
Vikas> wandering around in the dark?
Getting closer :-)
: So basically, a thread is simply a light-weight, less resource intensive
: variant of a process in that it eliminates the costly
: forking/context-switching, etc, right?
By George, I think you've got it!! Just add the clause "which shares the
same address space as any other thread of the process".
Fanatical purists will tell you we're oversimplifying, but that's the
purpose of a brief definition :-).
--
Larry Blanchard
Old roses, old motorcycles, old trains, and just plain old:)
Sure, it isn't true "parallel" without multiple CPUs, but it is the fake
parallel that most single CPU, pre-emptive multi-tasking OSes have used
for years. The big win of threads would be that you could have two
threads in the same address space with one waiting for IO and the other
doing something useful. Change point of execution, but keep all the
system buffers (cache, MMU, etc) as they were. Much less expensive for
the system. Also many programmers think multiple threads are easier to
program (some do disagree).
> > [HTTP request processing ]
>
> > - read the request (and possibly an input document)
> > - perform the requested action
> > - return the result and any output document
>
> >During any of these stages, it may be necessary to wait for some event,
> >such as more data arriving, or output buffer space on the socket, or
> >completion of a disk access, whatever. In a single-threaded program
> >this is hard to handle efficiently; you end up having to write the
> >request-processing code such that it represents its internal state
> >as data rather than in the program flow. In a multi-threaded or
> >multi-process implementation, on the other hand, the code is simple,
> >and when one thread/process is blocked waiting for something, the CPU
> >is available for use by other threads or processes.
>
> Arent you using threads and processes in an interchangeable fashion here? One
> of my questions in my initial posting was exactly this i.e. can threads and
> processes be used interchangeably and the answer was a resounding NO.
I missed the start of this, but they are not the same. Each process has
a unique address space, while threads of the same process share the same
address space. Change a variable in one and you alter the other. You
can pass pointers between threads of the same process, while you cannot
do this across process boundries. Maybe it would help to think of
threads as processes where every byte of memory is shared between them.
The differences are more than this, but it is a start.
> In the scenario you describe above, cant each step in the processes be
> performed by a fork()ed process? Before you hasten to chastize me, I agree
> that forking would be a more expensive solution in the above situation, but it
> is *possible*, right? That would eliminate the 'wait for I/O' or 'wait for
> XXX' problem.
Kinda, but now the data is in one process and the action was done by
another. How will you syncrhonize the two? Sharred memory? Sockets?
It would be expensive and non-obvious to whomever had to maintain this
software.
> So basically, a thread is simply a light-weight, less resource intensive
> variant of a process in that it eliminates the costly
> forking/context-switching, etc, right?
You are getting warmer, but still incomplete.
> Parallel execution is not the point really since both threads and processes
> can run in parallel (or can they? see my first question above)
Sure, it isn't true parallel without the right hardware. But you can
load one varuavke from disk while dumping the second to a TCP/IP socket.
> >Remember that in a "non-threaded" system, you still actually have
> >threads, exactly one thread per process. Having multiple threads on
> >a single CPU is useful in the same ways as having multiple processes
> >on a single CPU.
>
> Err.. you mean 'having multiple processes on multiple CPUs' dont you?
No. Simply put a thread is a "point of execution" and a process is an
"address space". In a standard system there is one point of excution
(thread) per address space (process), but this doesn't have to be the
case (multi-threaded systems).
> Thanks for your continued help. Am I getting close or still wandering around
> in the dark?
As I said, I missed the beginning, but I'd say that you're fairly close.
> Regards,
> Vikas
Have you ever used something like XINU (Comer's unix like OS from the
80s)? Here you have multiple "processes" but only a single address
space. Using modern Unix terminology these "processes" would actually
be threads and there was only one process (which did include the
kernal). On non-MMU systems, this would be the norm (you need a MMU to
have true processes). MS-Windows was like this where things would
change between windows, but a run-away pointer could bother any other
application on the system.
- doug
>Waiting for I/O?
>If a processes under UNIX is waiting for IO say in read() is'nt it in kernel
>mode? I mean it is a system call, thus if its in kernel mode, how can it
>have another thread doing something useful? Or is that "allowed".
>I've been watching this little thread discussion with interest...
That's when kernel threads become useful; traditionally, Unix already
allowed otehr processes to run if one was blocked for I/O. W/ kernel
threads, one thread can block in the kernel, but the other threads can
simply go about their tasks. W/o assistance from the kernel (a user
mode threads package) you get into quite messy non-blocking I/O stuff
quickly. (And non-blocking I/O is typically only implemented for "slow"
devices, i.e., pipes, sockets, but not for "fast" read/write operations
to disk. Nor do you get any advantage of running one process on
multiple CPUs.
With kernel threads it's possible for one thread to be stopped in I/O,
even if it's a page fault. And you can run on multiple CPUs with one
process.
Casper
--
Expressed in this posting are my opinions. They are in no way related
to opinions held by my employer, Sun Microsystems.
Statements on Sun products included here are not gospel and may
be fiction rather than truth.
ShadowS> Waiting for I/O? If a processes under UNIX is waiting for
ShadowS> IO say in read() is'nt it in kernel mode?
Yup.
ShadowS> I mean it is a system call, thus if its in kernel mode, how
ShadowS> can it have another thread doing something useful? Or is
ShadowS> that "allowed".
Depends on whether threading is implemented in the kernel or purely
in user-mode.
>for years. The big win of threads would be that you could have two
>threads in the same address space with one waiting for IO and the other
>doing something useful. Change point of execution, but keep all the
Waiting for I/O?
If a processes under UNIX is waiting for IO say in read() is'nt it in kernel
mode? I mean it is a system call, thus if its in kernel mode, how can it
have another thread doing something useful? Or is that "allowed".
I've been watching this little thread discussion with interest...
>address space. Change a variable in one and you alter the other. You
>can pass pointers between threads of the same process, while you cannot
>do this across process boundries. Maybe it would help to think of
>threads as processes where every byte of memory is shared between them.
>The differences are more than this, but it is a start.
I can imagine how changing a variable would be alot simpler than using
conventional IPC methods.
--
Thamer Al-Herbish
sha...@whitefang.com
sha...@kuwait.net
Some I/O is in kernel mode, but often the devices are slower than the
CPU, so while the disk (or whatever) does its thing, the OS lets another
job run. Just because one thread is blocked for I/O, another can still
burn CPU cycles.
Think of the standard consumer/producer type problem. Let one thread
worry about consumers and the other worry about producers. Each has its
own network socket (or whatever IPC interface you prefer) to worry
about. The only thing they have in common is the data buffer and
control variables (ie - process local semaphores to regulate the
buffers). While the consumer is waiting for a slow network transfer,
that thread is blocked, but nothing stops the producer from shovelling
data across a faster connection. If this had been a single threaded
process, then there would be no production while waiting for a single
slow consumer.
- doug
................... In case of user level threads, if a thread is waiting
in a system call then all the threads should wait(?). In case of kernel
supported user threads (i.e. Light Weight Processes), since kernel
schedules them, one thread can wait in a system call while other threads
doing something else.
>
> >address space. Change a variable in one and you alter the other. You
> >can pass pointers between threads of the same process, while you cannot
> >do this across process boundries. Maybe it would help to think of
> >threads as processes where every byte of memory is shared between them.
> >The differences are more than this, but it is a start.
>
> I can imagine how changing a variable would be alot simpler than using
> conventional IPC methods.
But you have to provide mutual exclusion while accessing a global variable
using mutexes or some other means.
Bye
------
Chandrama Mishra
>
> --
> Thamer Al-Herbish
> sha...@whitefang.com
> sha...@kuwait.net
-------------------==== Posted via Deja News ====-----------------------
http://www.dejanews.com/ Search, Read, Post to Usenet