# 归档文件 - 实验一 进程与线程——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 实验准备 1. **fork() 系统调用** ```cpp pid = fork(); ``` 创建一个子进程,子进程是父进程的完整复制,正常返回值为非负整数。对于父进程返回值大于 0(子进程 pid),对于子进程返回 0,利用返回值差别执行不同逻辑。 2. **clone() 系统调用** ```cpp 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:传递参数 3. **pipe() 系统调用** ```cpp int pipe(int fd[2]); ``` 创建管道,返回 fd[0](读)、fd[1](写),可被 fork() 子进程继承共享。 4. **信号量与互斥锁** - sem_wait(&s):P 操作;sem_post(&s):V 操作 - pthread_mutex_lock(&mutex):加锁;pthread_mutex_unlock(&mutex):解锁 ## 1.4 实验设计 1. 用 pipe() 创建管道,fork() 创建 2 生产者 + 2 消费者进程,管道通信。 2. 用 clone() 创建 4 个轻进程(线程),共享内存,互斥锁保护共享区。 ## 1.6 实验结果 - fork() 进程独立地址空间,通过管道通信,数据互不影响。 - clone() 线程共享内存,需互斥与同步,数据一致。 ## 1.7 思考问题 1. 用 shm/msg 实现生产者-消费者。 2. 对比 pipe、clone、shm、msg 优缺点与适用场景。