操作系统是中断驱动的
创建进程:
1.父进程与子进程并发执行
2.父进程等待子进程结束
子进程空间两种情况:
1.子进程是父进程的复制品
2.子进程重新装载另一端程序
父进程:fork 返回子进程pid>0 可用wait 等待子进程结束
子进程:fork 返回 pid =0 用execlp 装载
两个fork 的例子
int main() { pid_t pid; /* fork another process */ pid = fork(); if (pid < 0) { /* error occurred */ fprintf(stderr, "Fork Failed"); exit(-1); } else if (pid == 0) { /* child process */ execlp("/bin/ls", "ls", NULL); } else { /* parent process */ /* parent will wait for the child to complete */ wait (NULL); printf ("Child Complete"); exit(0); } }
#include <sys/types.h>
#include<stdio.h>
#include<unistd.h>
int value = 5;
int main()
{
pid_t pid;
pid = fork();
if (pid == 0)
value+=15;
else if (pid>0)
{
wait(NULL);
printf(“parent: value = %d”,value);
exit(0);
}
}
生产者-消费者 进程代码(共享缓冲区)
Solution is correct, but can only use BUFFER_SIZE-1 elements
#define BUFFER_SIZE 10
typedef struct {
. . .
} item;
item buffer[BUFFER_SIZE];
int in = 0;//缓冲区下一个位置
int out = 0;//第一个非空缓冲区
生产者 inset()
while (true) { /* Produce an item */
while (((in + 1) % BUFFER SIZE count) == out)
; /* do nothing -- no free buffers */
buffer[in] = item;
in = (in + 1) % BUFFER SIZE;
}
消费者 remove ()
while (true) {
while (in == out)
; // do nothing -- nothing to consume
// remove an item from the buffer
item = buffer[out];
out = (out + 1) % BUFFER SIZE;
return item;
}
进程间通信
1.直接通信,明确的命名通信的发送者和接受者
send (P, message) – send a message to process P
receive(Q, message) – receive a message from process Q
非对称编址
Send(p, message)Receive(id, message)
2.间接通信, 通过邮箱/端口发送接收
Each mailbox has a unique id
Processes can communicate only if they share a mailbox
create a new mailbox
send and receive messages through mailbox
destroy a mailbox
send(A, message) – send a message to mailbox A
receive(A, message) – receive a message from mailbox A
Mailbox sharing
P1, P2, and P3 share mailbox A
P1, sends; P2 and P3 receive
Who gets the message?
Allow a link to be associated with at most two processes
Allow only one process at a time to execute a receive operation
Allow the system to select arbitrarily the receiver. Sender is notified who the receiver was.
同步
Message passing may be either blocking or non-blocking
Blocking is considered synchronous
Blocking send makes the sender blocked until the message is received
Blocking receive makes the receiver blocked until a message is available
Non-blocking is considered asynchronous
Non-blocking send makes the sender to send the message and to continue
Non-blocking receive makes the receiver receive a valid message or null
缓冲
Queue of messages attached to the link; implemented in one of three ways
1. Zero capacity – 0 messages Sender must wait for receiver (rendezvous)
2. Bounded capacity – finite length of n messages Sender must wait if link full
3. Unbounded capacity – infinite length Sender never waits
线程
A running entity of a process, and a unit that can be scheduled independently.
A basic unit of CPU utilization
Resources still belong to process
Code section
Data section
Open files
signals
Thread is a running unit (smallest unit)
Thread has few resources (counter, register, stack), shares all the resources that the process has.
User Level Thread
Thread management done by user-level threads library
Kernel knows nothing about threads
Implementedby thread libraryCreate,cancellationTransferdata or messageSaveand recover the context of threadsThekernel manage the process, but know nothing about threadWhena thread have a system call, the process will be blocked. To thread library,the thread’s state is running
Kernel level thread
All threads are managed by the kernel
Create, cancellation and schedule
No thread library, but provide API
Kernel maintains context of threads and processes
The switch between threads needs the support of kernel
多线程问题;
Does fork() duplicate only the calling thread or all threads?
Exec() is after fork()
No exec() after fork()