2.7 KiB
2.7 KiB
归档文件 - 实验一 进程与线程——Linux 进程与线程通信
1.1 实验目的
深刻理解线程和进程的概念,掌握线程与进程在组成成分上的差别,以及与其相适应的通信方式和应用目标。
Linux 系统的 fork() 保持了 UNIX 的经典语义,被创建进程具有独立于父进程的地址空间,二者之间的通信通常可以采用 pipe 机制。clone() 是 Linux 系统特有的系统调用,可以通过参数确定父子之间是否共享存储空间等资源,在地址空间等资源共享的情况下 clone() 实质上相当于创建了一个轻进程或线程,这是 clone() 的通常用法。实际在 Linux 系统中,fork() 以及用户级线程 pthread 都是基于 clone() 实现的。
1.2 实验内容
以 Linux 系统进程和线程机制为背景,掌握 fork() 和 clone() 系统调用的形式和功能,以及与其相适应的高级通信方式。由 fork() 派生的子进程之间通过 pipe 通信,由 clone() 创建的线程之间通过共享内存通信,对于后者需要考虑互斥问题。
以生产者-消费者问题为例,通过实验理解 fork() 和 clone() 两个系统调用的区别。程序要求能够创建 4 个进程或线程,其中包括两个生产者和两个消费者,生产者和消费者之间能够传递数据。
1.3 实验准备
- fork() 系统调用
pid = fork();
创建一个子进程,子进程是父进程的完整复制,正常返回值为非负整数。对于父进程返回值大于 0(子进程 pid),对于子进程返回 0,利用返回值差别执行不同逻辑。
- clone() 系统调用
int clone(int (*fn)(void *arg), void *stack, int flags, void *arg);
- fn:轻进程执行函数
- stack:轻进程使用栈
- flags:CLONE_VM/CLONE_FS/CLONE_FILES/CLONE_SIGHAND/CLONE_PID 组合
- arg:传递参数
- pipe() 系统调用
int pipe(int fd[2]);
创建管道,返回 fd[0](读)、fd[1](写),可被 fork() 子进程继承共享。
- 信号量与互斥锁
- sem_wait(&s):P 操作;sem_post(&s):V 操作
- pthread_mutex_lock(&mutex):加锁;pthread_mutex_unlock(&mutex):解锁
1.4 实验设计
- 用 pipe() 创建管道,fork() 创建 2 生产者 + 2 消费者进程,管道通信。
- 用 clone() 创建 4 个轻进程(线程),共享内存,互斥锁保护共享区。
1.6 实验结果
- fork() 进程独立地址空间,通过管道通信,数据互不影响。
- clone() 线程共享内存,需互斥与同步,数据一致。
1.7 思考问题
- 用 shm/msg 实现生产者-消费者。
- 对比 pipe、clone、shm、msg 优缺点与适用场景。