Transcript Document

Chapter 10
Multitasking
Chapters 5 and
6 cover the highest
layer
Chapters 7 and 9
cover the lowest
layer
10.1 Imperative
Programs
A programming language that expresses a computation
as a sequence of operations is called an imperative
language. C is an imperative language.
1 int main(void) {
2 addListener(&print);
3 addListener(&print);
4 update(1);
5 addListener(&print);
6 update(2);
7 return 0;
8}
Who can give output?
11222
10.2 Threads
10.2.1 Creating Threads
Who can explain the program ?
10.2.2 Implementing Threads
Note
 Threads may or may not begin running when created.
 A thread may be suspended between any two atomic
instructions to execute an other thread and/or interrupt
service routine.
 Threads can often be given priorities, and these may
or may not be respected by the thread schedule.
Threads may block on semaphores(信号灯) and
mutexes(互斥).
a jiffy is the time interval at which the systemclock ISR is invoked.
10.2.3 Mutual Exclusion
Suppose that addListener is called from more
than one thread. Then what could go wrong?
One way to prevent such disasters is by using a mutual
exclusion lock (or mutex), as illustrated in the next
example.
Who can explain?
Example 10.10: The update procedure in Figure 10.2
does not modify the list of listeners, but it does read the
list. Suppose that thread A calls addListener and gets
suspended just after line 21, which does this:
What will happen on line 33 when element == tail->next?
The mutex added in Example 10.9 is not sufficient to
prevent this disaster. The mutex does not prevent thread A
from being suspended.
Thus, we need to protect all accesses of the data structure
with mutexes, which we can do by modifying update as
follows
10.2.4 Deadlock
A deadlock occurs when some threads become
permanently blocked trying to acquire locks.
This can occur, for example, if thread A holds lock1 and
then blocks trying to acquire lock2, which is held by
thread B, and then thread B blocks trying to acquire
lock1.
Who can give some experience of deadlock?
Operating Systems
dominant general-purpose Oss
• Microsoft Windows
• Mac OS X, Linux,
Embedded
• Windows CE (WinCE) (from Microsoft), VxWorks
• QNX, Embedded Linux
Mobile operating systems
• Symbian OS, Android,
• BlackBerry OS, iPhone OS
• Palm OS, Windows Mobile
10.2.6 The Problem with Threads
如果:A线程在释放
LOCK后被挂起,B
线程修改了newx的
值,结果A线程恢复
后,输出是?
被修改前的newx的
值
10.3 Processes and Message Passing
Processes are imperative programs with their own
memory spaces. These programs cannot refer to each
others’ variables, and consequently they do not exhibit
the same difficulties as threads.
Communication between the programs must occur via
mechanisms provided by the operating system,
microkernel, or a library.
One such mechanism that has fewer difficulties is a file
system.
A more flexible mechanism for communicating between
processes is message passing. Here, one process
creates a chunk of data, deposits it in a carefully
controlled section of memory that is shared, and then
notifies other processes that the message is ready.
This program uses a
producer/consumer
pattern, where one
thread produces a
sequence of
messages (a stream),
and another thread
consumes the
messages.
Figure 10.5 A simple example of a
message passing program
唤醒进程
挂起,直至sent,
mutex被释放
Figure 10.6: Message-passing
procedures to send and get
messages
Suppose that lines 23 and 24 were reversed, and
pthread cond signal were called after releasing the
mutex lock. What will happen?
Then in this case, it would be possible for pthread cond
signal to be called while the consumer thread is
suspended (but not yet blocked) between lines 30 and
31. In this case, when the consumer thread resumes, it
will execute line 31 and block, waiting for a signal. But
the signal has already been sent! And it may not be sent
again, so the consumer thread could be permanently
blocked.
Notice further on line 31 that pthread cond wait takes
&mutex as an argument.
In fact, while the thread is blocked on the wait, it
releases the mutex lock temporarily.
If it were not to do this, then the producer thread would
be unable to enter its critical section, and therefore
would be unable to send a message. The program
would deadlock.
什么是PV操作?
The implementation of the producer/consumer
pattern in Example 10.13, in fact, has a fairly
serious flaw.
Specifically, it imposes no constraints on the
size of the message queue.
What will happen?
This can be fixed by limiting the size of the
buffer.
Q&A