fork() 进程

本文详细介绍了Linux中的fork()函数如何创建进程,包括进程间的独立性和共享性,写时复制技术(Copy-On-Write)的工作原理,以及在代码中的实际运用和可能遇到的问题,如僵尸进程和孤儿进程。通过示例展示了fork()函数在循环中的行为,讨论了变量内存地址变化的原因。
摘要由CSDN通过智能技术生成

https://note.youdao.com/s/71lWGFsI
图片我懒的粘贴过来了,上面是源笔记链接,想看全的请移步。
进程是系统中基本的执行单位。
Linux中,用户可以创建子进程,子进程存在系统中,独立于父进程,子进程可以接受系统的调度,可以分配得到系统资源。系统可以检查到子进程的存在,且可以拥有与父进程同样的权利。

fork()函数不需要传入参数,返回值是一个进程的ID,一次调用返回俩个值。一个是返回给父进程的,父进程得到的是创建子进程时候,子进程的ID。另一个是返回给子进程,子进程得到的是一个pid_t = 0 的值,由于0号进程是内核进程,所以子进程的进程号不可能为0,所以可以用来区别谁是父,谁是子。

fork()流程
fork()在创建一个进程后,并从内核中分配一个进程ID(新ID)给在个新进程。然后为这个新进程分配进程空间,并将父进程的进程空间中的内容复制到子进程的进程空间中,这些被复制的内容包括:数据段、堆栈段(在虚拟地址空间上父进程与子进程,数据段与堆栈段是不一样的,但是在实际物理地址空间上,他们是共同使用一段物理地址空间。只有当子进程开始修改父进程的数据段或堆栈段的时候,才会为子进程分配一段新数据段、堆栈段的物理地址空间。这就是的是写时复制)。然后代码段是与父进程共享的。所以创建出来的子进程其实就是父进程的一个复制版。
如果代说码段不是共享的话,那么操作系统需要:
为子进程的页表分配页帧
为子进程的页分配页帧
初始化子进程的页表
把父进程的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在两个非fork进程中实现共享内存读写的同步,可以使用信号量(semaphore)来实现。信号量是一种进程间通信机制,用于实现进程的同步与互斥。 下面是一个使用semop实现共享内存读写同步的示例代码: ```c #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> #include <sys/shm.h> #define SHM_SIZE 1024 union semun { int val; struct semid_ds *buf; unsigned short *array; }; int main() { int shmid, semid; char *shmaddr; union semun sem_union; struct sembuf sem_op; // 创建共享内存 shmid = shmget(IPC_PRIVATE, SHM_SIZE, IPC_CREAT | 0666); if (shmid == -1) { perror("shmget error"); exit(EXIT_FAILURE); } // 连接共享内存 shmaddr = shmat(shmid, NULL, 0); if (shmaddr == (char *) -1) { perror("shmat error"); exit(EXIT_FAILURE); } // 创建信号量 semid = semget(IPC_PRIVATE, 1, IPC_CREAT | 0666); if (semid == -1) { perror("semget error"); exit(EXIT_FAILURE); } // 初始化信号量 sem_union.val = 0; if (semctl(semid, 0, SETVAL, sem_union) == -1) { perror("semctl error"); exit(EXIT_FAILURE); } // 写入共享内存 sem_op.sem_num = 0; sem_op.sem_flg = 0; sem_op.sem_op = -1; // P操作 if (semop(semid, &sem_op, 1) == -1) { perror("semop error"); exit(EXIT_FAILURE); } printf("Enter a message: "); fgets(shmaddr, SHM_SIZE, stdin); sem_op.sem_num = 0; sem_op.sem_flg = 0; sem_op.sem_op = 1; // V操作 if (semop(semid, &sem_op, 1) == -1) { perror("semop error"); exit(EXIT_FAILURE); } // 读取共享内存 sem_op.sem_num = 0; sem_op.sem_flg = 0; sem_op.sem_op = -1; // P操作 if (semop(semid, &sem_op, 1) == -1) { perror("semop error"); exit(EXIT_FAILURE); } printf("Received message: %s", shmaddr); sem_op.sem_num = 0; sem_op.sem_flg = 0; sem_op.sem_op = 1; // V操作 if (semop(semid, &sem_op, 1) == -1) { perror("semop error"); exit(EXIT_FAILURE); } // 删除信号量和共享内存 if (semctl(semid, 0, IPC_RMID, sem_union) == -1) { perror("semctl error"); exit(EXIT_FAILURE); } if (shmdt(shmaddr) == -1) { perror("shmdt error"); exit(EXIT_FAILURE); } if (shmctl(shmid, IPC_RMID, NULL) == -1) { perror("shmctl error"); exit(EXIT_FAILURE); } return 0; } ``` 在上面的示例代码中,我们先创建了一个共享内存和一个信号量。然后,在写入共享内存前,我们使用了P操作来获取信号量,以确保共享内存可写。接下来,我们从标准输入中读取一行内容,并将其写入共享内存。完成后,我们使用V操作释放信号量,以确保其他进程可以读取共享内存。 读取共享内存的方式类似,我们先使用P操作获取信号量,然后读取共享内存中的内容,最后使用V操作释放信号量,以确保其他进程可以继续写入共享内存。最后,我们删除了信号量和共享内存。 需要注意的是,上面的示例代码中只使用了一个信号量,因此只能保证单个进程的读写同步。如果有多个进程需要读写共享内存,需要使用多个信号量来实现不同进程之间的同步。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值