更多配套资料CSDN地址:点赞+关注,功德无量。更多配套资料,欢迎私信。
上午: 进程
下午:编写shell
教学内容:
1、进程和程序最本质的区别是程序是静态的,而进程是动态的。
2、进程调度:先进先出原则,短进程优先原则,优先级原则,随机原则。
3、进程控制块(PCB):PCB是操作系统中最重要的记录型数据结构。PCB中记录了用于描述进程进展情况及控制进程运行所需的全部信息。在Linux中PCB存放在task_struct结构体中。
4、每个进程都有一个非负整型数表示的唯一进程ID。进程ID标识符总是唯一的,但进程ID可以重用。当一个进程终止后,其进程ID就可以再次使用了。(但要等待一些时间才能重新使用这个进程ID)
5、进程号(PID),父进程号(PPID),进程组号(PGID);Linux操作系统提供了三个获得进程号的函数getpid()、getppid()、getpgid();每一个进程都是别的进程中开启的,linux中0进程是进程调度,1进程是进程初始化。
6、在linux环境下,创建进程的主要方法是调用以下两个函数:fork();vfork();
新的数据类型pid_t,实际上就是整型,是为进程号;
#include <sys/types.h>
#include <unistd.h>
pid_t fork(void);pid=fork();pid返回进程号,在父进程中pid是子进程的进程号,在子进程中是pid为0;子进程把父进程的环境复制了一份,(注意不是说子进程号为0;)能父进程和子进程同时进行,程序结构是:
pid=fork();
if(pid<0)
perror("fork");
else if(pid==0)
{
。。。。
}
else
{
。。。。
}
~~~~~~~~~~~~~~~~~~~~~~~~
关于对指向地址的子进程操作不会改变父进程该地址的值问题?
int *p = (int*) malloc(sizeof(int));
// p = 0xDEAD BEEF
pid = fork();
if (pid == 0) {
// child process
p 指向的是新进程中的 0xDEAD BEEF 内存位置
}
else {
// parent process
*p = 1; // 修改的是父进程内存中 0xDEAD BEEF 位置
}
虽然两个指针指向的相对位置相同,但是两个地址是分散在两个进程地址空间中的。
~~~~~~~~~~~~~~~~~~~~~~~~~~
pid_t vfork(void);pid=fork();pid返回进程号,在父进程中pid是子进程的进程号,在子进程中是pid为0;(注意不是说子进程号为0;),子进程是在父进程的环境运行,仅仅重启了一个新的进程,在运行中必须先保证子进程运行结束才会运行父进程和fork完全不同
pid=fork();
if(pid<0)
perror("fork");
else if(pid==0)
{
。。。。
_exit(0); //或者execl(),要不结束这个进程,要不重启函数替代这个新的进程;结束这个进程不要改变父进程的环境,所以不能调用exit()函数。
}
else
{
。。。。
}
7、wait和waitpid:
pid_t wait(int *status):等待上一个进程的返回值赋值给*status;
如果执行成功则返回子进程ID
出错返回-1,失败原因存于errno中;可以用以下的宏来判断status的情况。
pid_t waitpid(pid_t pid, int *status,int options):等待指定进程结束