操作系统实验报告5

实验内容

  • 实验内容:进程的创建和终止。

    • 编译运行课件 Lecture 06 例程代码:Algorithm 6-1 ~ 6-6.

实验环境

  • 架构:Intel x86_64 (虚拟机)
  • 操作系统:Ubuntu 20.04
  • 汇编器:gas (GNU Assembler) in AT&T mode
  • 编译器:gcc

技术日志

  • 验证实验alg.6-1-fork-demo.c

源代码:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>int main(void)
{int count = 1;pid_t childpid;childpid = fork(); /* child duplicates parent’s address space */if (childpid < 0) {perror("fork()");return EXIT_FAILURE;}else /* fork() returns 2 values: 0 for child pro and childpid for parent pro */if (childpid == 0) { /* This is child pro */count++;printf("Child pro pid = %d, count = %d (addr = %p)\n", getpid(), count, &count); }else { /* This is parent pro */printf("Parent pro pid = %d, child pid = %d, count = %d (addr = %p)\n", getpid(), childpid, count, &count);sleep(5);wait(0); /* waiting for all children terminated */}printf("Testing point by %d\n", getpid()); /* child executed this statement and became defunct before parent wait() */return EXIT_SUCCESS;
}

执行程序命令:

gcc alg.6-1-fork-demo.c
./a.out

执行截图:

分析:

实验内容原理:

fork()函数会创建一个新进程,即子进程,这个子进程直接拷贝父进程的数据段、代码段、堆、栈,父子进程并不共享这些存储空间,子进程有独立的地址空间,子进程和父进程一样都启动一个从fork系统调用之后的下一条指令开始执行的线程,父子进程的执行次序是不确定的。

fork()函数成功调用一次返回两次,一次在子进程中返回,一次在父进程中返回,返回的两个值,子进程返回0,父进程返回子进程的进程号ID,调用出错返回-1。

实现细节解释:

程序一开头,首先int count = 1声明变量count为1

然后pid_t childpidchildpid = fork()使用fork()函数创建一个新进程,这个新建的子进程直接拷贝父进程的数据段和代码段,返回一个进程号并把这个进程号赋给pid_t进程号类型变量childpid

接下来是选择分支语句,如果变量childpid小于0,说明在fork()的过程中出错,则进行错误处理,将错误原因"fork()"函数出错输出到标准设备(stderr),并返回EXIT_FAILURE代表异常退出。

如果fork()函数在执行过程中没有出错,则继续进入一个判断变量childpid值的选择分支语句,若变量childpid为0,说明是子进程,执行结果为变量count自增,打印当前进程的进程号(即子进程),变量count的值及其虚拟地址;

若变量childpid大于0,说明是父进程,执行结果为直接打印当前进程的进程号(即父进程),变量childpid(子进程ID),变量count的值及其虚拟地址,然后使用sleep(5)让父进程休眠5s,并用wait(0)让父进程等待所有子进程结束后再执行,这样就保证了父进程再子进程结束之后再执行。

跳出这个判断一个进程是子进程还是父进程的分支语句后,无论是子进程还是父进程,程序都会执行一个打印测试点语句Testing point by,打印当前进程的进程号,并返回EXIT_SUCCESS代表正常退出。

从上图可以看到,子进程中的变量count与父进程中的变量count具有相同的虚拟地址,但是子进程中的count值与父进程中的count值不同,这是因为fork()得到的子进程具有独立的地址空间,子进程中的count变量被映射到了和父进程不同的物理地址,所以子进程中的count变量的值变为2后,并没有影响父进程中count变量的值仍为1。

从上图可以看到,父进程的进程号为6452,子进程的进程号为6453,Testing point by后面接的数字是当前执行进程的进程号,可以看到,进程号为6453的进程先执行完打印测试点语句,然后进程号为6452的进程再执行打印测试点语句,即先执行的是子进程,子进程执行完后,父进程再执行,由父进程的选择分支语句中的sleep(5)wait(0)保证了这一执行先后顺序。

  • 验证实验alg.6-2-vfork-demo.c

源代码:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>int main(void)
{int count = 1;pid_t childpid;childpid = vfork(); /* child shares parent’s address space */if (childpid < 0) {perror("fork()");return EXIT_FAILURE;}else /* vfork() returns 2 values: 0 for child pro and childpid for parent pro */if (childpid == 0) { /* This is child pro, parent hung up until child exit ...  */count++;printf("Child pro pid = %d, count = %d (addr = %p)\n", getpid(), count, &count); printf("Child taking a nap ...\n");sleep(5);printf("Child waking up!\n");_exit(0); /* or exec(0); "return" will cause stack smashing */}else { /* This is parent pro, start when the vforked child finished */printf("Parent pro pid = %d, child pid = %d, count = %d (addr = %p)\n", getpid(), childpid, count, &count);wait(0); /* not waitting this vforked child terminated*/}printf("Testing point by %d\n", getpid()); /* executed by parent pro only */return EXIT_SUCCESS;
}

执行程序命令:

gcc alg.6-2-vfork-demo.c
./a.out

执行截图:

分析:

实验内容原理:

vfork()函数会创建一个新进程,即子进程,这个子进程直接共享父进程的数据段,并且将父进程挂起,保证先执行子进程,在调用exec函数或_exit函数之前和父进程数据是共享的,在它调用exec函数或_exit函数之后父进程才会被恢复调度运行。

和fork()函数一样,vfork()函数成功调用一次返回两次,一次在子进程中返回,一次在父进程中返回,返回的两个值,子进程返回0,父进程返回子进程的进程号ID,调用出错返回-1。

实现细节解释:

程序一开头,首先int count = 1声明变量count为1

然后pid_t childpidchildpid = vfork()使用vfork()函数创建一个新进程,这个新建的子进程共享父进程的数据段,并将父进程挂起,返回一个进程号并把这个进程号赋给pid_t进程号类型变量childpid

接下来是选择分支语句,如果变量childpid小于0,说明在vfork()的过程中出错,则进行错误处理,将错误原因输出到标准设备(stderr),并返回EXIT_FAILURE代表异常退出。

如果vfork()函数在执行过程中没有出错,则继续进入一个判断变量childpid值的选择分支语句,若变量childpid为0,说明是子进程,执行结果为变量count自增,打印当前进程的进程号(即子进程),变量count的值及其虚拟地址,再打印Child taking a nap ...,使用sleep(10)语句让子进程休眠10s,此时父进程并没有执行,说明父进程被挂起,等待子进程调用exec或_exit函数后才接着执行,接着打印Child waking up!,最后使用_exit(0)直接退出子进程,同时使父进程恢复执行,跳过了最后的打印测试点Testing point by语句;

若变量childpid大于0,说明是父进程,执行结果为直接打印当前进程的进程号(即父进程),变量childpid(子进程ID),变量count的值及其虚拟地址,然后使用wait(0)让父进程等待所有子进程结束后再执行。

跳出这个判断一个进程是子进程还是父进程的分支语句后,程序会执行一个打印语句,打印当前进程的进程号,并返回EXIT_SUCCESS代表正常退出。

子进程中的变量count与父进程中的变量count具有相同的虚拟地址。子进程的count值与父进程的count值相同,它们共享同一存储空间,被映射到同一物理地址。

父进程被挂起,直到vfork的子进程执行了execv函数才继续执行。

子进程在Testing point by语句之前就退出,只有父进程执行了这一打印语句。

  • 验证实验alg.6-3-fork-demo-nowait.c

源代码:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
// #include <sys/wait.h>int main(void)
{int count = 1;pid_t childpid;childpid = fork(); /* child duplicates parent’s address space */if (childpid < 0) {perror("fork()");return EXIT_FAILURE;}elseif (childpid == 0) { /* This is child pro */count++;printf("child pro pid = %d, count = %d (addr = %p)\n", getpid(), count, &count); printf("child sleeping ...\n");sleep(10); /* parent exites during this period and child became an orphan */printf("\nchild waking up!\n");}else { /* This is parent pro */printf("Parent pro pid = %d, child pid = %d, count = %d (addr = %p)\n", getpid(), childpid, count, &count);}printf("\nTesting point by %d\n", getpid()); /* executed both by parent and child */return EXIT_SUCCESS;
}

执行程序命令:

gcc alg.6-3-fork-demo-nowait.c
./a.outps -l

执行截图:

分析:

实验内容原理:

使用fork()函数创建一个新的子进程,但不在父进程的选择分支语句中使用wait(0)语句保证父进程在子进程结束后执行,从而观察父进程和fork()创建出的子进程的执行次序。

实现细节解释:

程序一开头,首先int count = 1声明变量count为1

然后pid_t childpidchildpid = fork()使用fork()函数创建一个新进程,这个新建的子进程直接拷贝父进程的数据段和代码段,返回一个进程号并把这个进程号赋给pid_t进程号类型变量childpid

接下来是选择分支语句,如果变量childpid小于0,说明在fork()的过程中出错,则进行错误处理,将错误原因输出到标准设备(stderr),并返回EXIT_FAILURE代表异常退出。

如果fork()函数在执行过程中没有出错,则继续进入一个判断变量childpid值的选择分支语句,若变量childpid为0,说明是子进程,执行结果为变量count自增,打印当前进程的进程号(即子进程),变量count的值及其虚拟地址,再打印child sleeping ...,使用sleep(10)语句让子进程休眠10s,此时因为父进程中没有wait(0)语句,父进程不会等待子进程执行终止再执行,所以父进程会在子进程休眠的这段时间执行,最后打印child waking up!

若变量childpid大于0,说明是父进程,执行结果为直接打印当前进程的进程号(即父进程),变量childpid(子进程ID),变量count的值及其虚拟地址

跳出这个判断一个进程是子进程还是父进程的分支语句后,无论是子进程还是父进程,程序都会执行一个打印语句,打印当前进程的进程号,并返回EXIT_SUCCESS代表正常退出。

从上图可以看到,输入ps -l后,因为子进程中间休眠了10s,父进程中没有wait(0)语句,已经执行完后终止,剩下一个子进程处于休眠状态,变成孤儿进程,进程号pid=6951。

从上图可以看到,在什么都没有输入的情况下,进程号为6951的孤儿进程重新工作,打印child waking up!Testing point by语句,说明终端(bash)和分叉子级是异步工作的。

  • 验证实验alg.6-4-fork-demo-wait.c

源代码:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>int main(void)
{int count = 1;pid_t childpid, terminatedid;childpid = fork(); /* child duplicates parent’s address space */if (childpid < 0) {perror("fork()");return EXIT_FAILURE;}elseif (childpid == 0) { /* This is child pro */count++;printf("child pro pid = %d, count = %d (addr = %p)\n", getpid(), count, &count); printf("child sleeping ...\n");sleep(5); /* parent wait() during this period */printf("\nchild waking up!\n");}else { /* This is parent pro */terminatedid = wait(0);printf("Parent pro pid = %d, terminated pid = %d, count = %d (addr = %p)\n", getpid(), terminatedid, count, &count);}printf("\nTesting point by %d\n", getpid()); /* executed first by child and then parent */return EXIT_SUCCESS;
}

执行程序命令:

gcc alg.6-4-fork-demo-wait.c
./a.outps

执行截图:

分析:

实验内容原理:

使用fork()函数创建一个新的子进程,且在父进程的选择分支语句中使用wait(0)语句保证父进程在子进程结束后执行,并将wait(0)的返回值,即最后一个终止的子进程的进程号,赋给一个进程号类型pid_t变量terminatedid,再观察父进程和fork()创建出的子进程的执行次序。

实现细节解释:

程序一开头,首先int count = 1声明变量count为1

然后pid_t childpidchildpid = fork()使用fork()函数创建一个新进程,这个新建的子进程直接拷贝父进程的数据段和代码段,返回一个进程号并把这个进程号赋给pid_t进程号类型变量childpid

接下来是选择分支语句,如果变量childpid小于0,说明在fork()的过程中出错,则进行错误处理,将错误原因输出到标准设备(stderr),并返回EXIT_FAILURE代表异常退出。

如果fork()函数在执行过程中没有出错,则继续进入一个判断变量childpid值的选择分支语句,若变量childpid为0,说明是子进程,执行结果为变量count自增,打印当前进程的进程号(即子进程),变量count的值及其虚拟地址,再打印child sleeping ...,使用sleep(5)语句让子进程休眠5s,此时因为父进程中有wait(0)语句,父进程会等待子进程执行终止再执行,所以父进程不会在子进程休眠的这段时间执行,最后打印child waking up!

若变量childpid大于0,说明是父进程,执行结果为使用wait(0)函数,使子进程全部执行完后再执行父进程,并将返回值最后一个终止的子进程的进程号赋给一个进程号类型pid变量terminatedid,打印当前进程的进程号(即父进程),变量terminatedid,变量count的值及其虚拟地址

跳出这个判断一个进程是子进程还是父进程的分支语句后,无论是子进程还是父进程,程序都会执行一个打印语句,打印当前进程的进程号,并返回EXIT_SUCCESS代表正常退出。

从上图可以看到,父进程等待子进程执行完语句Testing point by,正常返回终止后,wait(0)将最后一个终止的子进程的进程号7357返回给变量terminatedid后,再执行程序,输入ps可以看到,子进程和父进程都结束终止了。

  • 验证实验alg.6-5-0-sleeper.c

源代码:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>int main(int argc, char* argv[])
{int secnd = 5;if (argc > 1) {secnd = atoi(argv[1]);if ( secnd <= 0 || secnd > 10)secnd = 5;}printf("\nsleeper pid = %d, ppid = %d\nsleeper is taking a nap for %d seconds\n", getpid(), getppid(), secnd); /* ppid - its parent pro id */sleep(secnd);printf("\nsleeper wakes up and returns\n");return 0;
}

执行程序命令:

gcc alg.6-5-0-sleeper.c
./a.out

执行截图:

分析:这是一个程序开始后,打印当前进程的pid,ppid的值和休眠秒数secnd的值,然后休眠secnd秒后,再继续执行,打印出sleeper wakes up and returns的简单程序。

  • 验证实验alg.6-5-vfork-execv-wait.c

源代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/stat.h>
#include <wait.h>int main(int argc, char* argv[])
{pid_t childpid;childpid = vfork();/* child shares parent's address space */if (childpid < 0) {perror("fork()");return EXIT_FAILURE;}elseif (childpid == 0) { /* This is child pro */printf("This is child, pid = %d, taking a nap for 2 seconds ...\n", getpid());sleep(2); /* parent hung up and do nothing */char filename[80];struct stat buf;strcpy(filename, "./alg.6-5-0-sleeper.o");if(stat(filename, &buf) == -1) {perror("\nsleeper stat()");_exit(0);}char *argv1[] = {filename, argv[1], NULL};printf("child waking up and again execv() a sleeper: %s %s\n\n", argv1[0], argv1[1]); execv(filename, argv1);
/* parent resume at the point 'execv' called. The vforked pro terminated and alg.6-5-sleeper.o spawned as child in the same childpid but with duplicated address space and returns to parent without any stack smashing. parent and child execute asynchronously */}else { /* This is parent pro, start when the vforked child terminated */printf("This is parent, pid = %d, childpid = %d \n", getpid(), childpid);/* parent executed this statement during the EXECV time */int retpid = wait(0); /* without wait(), the spawned EXECV may became an orphan */printf("\nwait() returns childpid = %d\n", retpid);}return EXIT_SUCCESS;
}

执行程序命令:

gcc alg.6-5-vfork-execv-wait.c
./a.outps -l

执行截图:

分析:

实验内容原理:

vfork()函数会创建一个新进程,即子进程,这个子进程直接共享父进程的数据段,并且将父进程挂起,保证先执行子进程,在调用exec函数或_exit函数之前和父进程数据是共享的,在它调用exec函数或_exit函数之后父进程才会被恢复调度运行。如果在vfork函数创建的子进程中使用了exec函数引发了一个新进程,那么这个新进程会继承原来的vfork出的子进程的进程号,新进程的父进程也为原来子进程的父进程,这个新进程并不与父进程共享一片存储空间,而是拥有独立的地址空间,并和父进程异步执行,但父进程中使用了wait(0),所以父进程会等待这个新的子进程执行完后,再执行终止。

实现细节解释:

首先pid_t childpidchildpid = vfork()使用vfork()函数创建一个新进程,这个新建的子进程共享父进程的数据段,返回一个进程号并把这个进程号赋给pid_t进程号类型变量childpid

接下来是选择分支语句,如果变量childpid小于0,说明在vfork()的过程中出错,则进行错误处理,将错误原因输出到标准设备(stderr),并返回EXIT_FAILURE代表异常退出。

如果vfork()函数在执行过程中没有出错,则继续进入一个判断变量childpid值的选择分支语句,若变量childpid为0,说明是子进程,打印当前进程的进程号(即子进程)和语句taking a nap for 2 sencods,使用sleep(2)语句让子进程休眠2s后继续执行,此时因为父进程被挂起,所以父进程并不会执行。

然后声明一个字符型数组,将字符串"./alg.6-5-0-sleeper.o"复制到这个数组中,并获取这个字符串代表的文件路径的文件信息,如果获取文件信息失败,进行错误处理,将错误原因输出到标准设备(stderr),并直接结束进程,否则打印出"./alg.6-5-0-sleeper.o"文件路径名和这个文件sleeper休眠秒数,execv(filename, argv)引发"./alg.6-5-0-sleeper.o"的文件sleeper作为新的子进程执行,同时父进程在execv()这个函数被调用后重新进行,和新的子进程异步执行。

若变量childpid大于0,说明是父进程,执行结果为直接打印当前进程的进程号(即父进程),然后使用wait(0),并把返回值最后一个结束的子进程的进程号赋给整型变量retpid,让父进程等待所有子进程结束后再执行,最后打印retpid

跳出这个判断一个进程是子进程还是父进程的分支语句后,返回EXIT_SUCCESS代表正常退出。

可以看到,在原来子进程休眠结束并调用了execv()函数引发了一个新的子进程sleeper,父进程也恢复执行后,新的子进程和父进程wait(0)之前的语句异步执行,并不能判断执行的先后次序,有时候是父进程先执行完,有时候是sleeper先执行完。

从上图可以看出,原来的子进程调用了execv()后产生的新的子进程sleeper继承了原来vfork出的子进程的进程号pid(7715),它们的父进程进程号都为7714,说明新的子进程sleeper的父进程是原来vfork出的子进程的父进程。

从上图可以看出,父进程在调用execv函数后重新运行,vfork出的子进程终止,sleeper被引发后作为新的子进程和之前的子进程有同一个进程号7715,也具有重复的地址空间,并且返回到父进程时,没有任何堆栈损坏。父进程和新的子进程异步执行。

无论如何,父进程需要等待它的子进程执行完终止后再执行,不然原来的子进程引发的sleeper进程作为新的子进程可能会变成孤儿进程。

  • 验证实验alg.6-6-vfork-execv-nowait.c

源代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/stat.h>
#include <wait.h>int main(int argc, char* argv[])
{pid_t childpid;childpid = vfork();/* child shares parent's address space */if (childpid < 0) {perror("fork()");return EXIT_FAILURE;}elseif (childpid == 0) { /* This is child pro */printf("This is child, pid = %d, taking a nap for 2 seconds ... \n", getpid());sleep(2); /* parent hung up and do nothing */char filename[80];struct stat buf;strcpy(filename, "./alg.6-5-0-sleeper.o");if(stat(filename, &buf) == -1) {perror("\nsleeper stat()");_exit(0);}char *argv1[] = {filename, argv[1], NULL};printf("child waking up and again execv() a sleeper: %s %s\n\n", argv1[0], argv1[1]);execv(filename, argv); /* parent resume at the point 'execv' called */}else { /* This is parent pro, start when the vforked child terminated */printf("This is parent, pid = %d, childpid = %d \n",getpid(), childpid);/* parent executed this statement during the EXECV time */printf("parent calling shell ps\n");system("ps -l");sleep(1);return EXIT_SUCCESS;/* parent exits without wait() and child may become an orphan */}
}

执行程序命令:

gcc alg.6-6-vfork-execv-nowait.c
./a.out

执行截图:

分析:

实验内容原理:

vfork()函数会创建一个新进程,即子进程,这个子进程直接共享父进程的数据段,并且将父进程挂起,保证先执行子进程,在调用exec函数或_exit函数之前和父进程数据是共享的,在它调用exec函数或_exit函数之后父进程才会被恢复调度运行。如果在vfork函数创建的子进程中使用了exec函数引发了一个新进程,那么这个新进程会继承原来的vfork出的子进程的进程号,新进程的父进程也为原来子进程的父进程,这个新进程并不与父进程共享一片存储空间,而是拥有独立的地址空间,并和父进程异步执行,这次父进程中不使用wait(0),那么由于执行次序不确定,所以新的子进程sleeper有可能成为孤儿进程,观察父进程和新的子进程sleeper的执行情况。

实现细节解释:

首先pid_t childpidchildpid = vfork()使用vfork()函数创建一个新进程,这个新建的子进程共享父进程的数据段,返回一个进程号并把这个进程号赋给pid_t进程号类型变量childpid

接下来是选择分支语句,如果变量childpid小于0,说明在vfork()的过程中出错,则进行错误处理,将错误原因输出到标准设备(stderr),并返回EXIT_FAILURE代表异常退出。

如果vfork()函数在执行过程中没有出错,则继续进入一个判断变量childpid值的选择分支语句,若变量childpid为0,说明是子进程,打印当前进程的进程号(即子进程)和语句taking a nap for 2 sencods,使用sleep(2)语句让子进程休眠2s后继续执行,此时因为父进程被挂起,所以父进程并不会执行。

然后声明一个字符型数组,将字符串"./alg.6-5-0-sleeper.o"复制到这个数组中,并获取这个字符串代表的文件路径的文件信息,如果获取文件信息失败,进行错误处理,将错误原因输出到标准设备(stderr),并直接结束进程,否则打印出"./alg.6-5-0-sleeper.o"文件路径名和sleeper休眠秒数,execv(filename, argv)引发"./alg.6-5-0-sleeper.o"的文件sleeper作为新的子进程执行,同时父进程在execv()这个函数被调用后重新进行,和新的子进程异步执行。

若变量childpid大于0,说明是父进程,执行结果为直接打印当前进程的进程号(即父进程),打印parent calling shell ps并使用系统调用命令system("ps -l")直接查看和bash相关的进程,然后使用sleep(1)语句让父进程休眠1s后继续执行,返回EXIT_SUCCESS代表正常退出。

从上图可以看到,bash的父进程的进程号pid为6106,start main()的父进程的父进程的进程号ppid也为6106,说明bash是start main()的父进程。

而start main()的父进程的进程号pid为8961,从vfork出的子进程中的execv()语句引发的sleeper进程的父进程的父进程的进程号ppid也为8961,说明start main()是sleeper的父进程。

start main()的父进程的进程号pid和system()父进程的父进程的进程号ppid相同,都为为8961,说明start main()是system()的父进程。

system()的父进程的进程号pid和system(“ps -l”)父进程的父进程的进程号ppid相同,都为为8963,说明system()是system(“ps -l”)的父进程。

start main()终止且控制权移交给了bash,从终端再输入"ps -l"

可以看到,由于父进程中没有使用wait(0),所以父进程在sleeper进程执行完前就终止了,sleeper成为了孤儿进程,又被进程号为1348的进程所收养作为子进程

终端(bash)和sleeper进程异步执行

进程号为1348的进程是"systemd"的守护进程(代替了"init")

操作系统实验报告5:进程的创建和终止相关推荐

  1. Linux进程的创建和父子进程同步,操作系统实验报告_Linux进程创建与通信.doc

    操作系统实验报告_Linux进程创建与通信 2011-2012学年第一学期 专 业: 班 级: 学 号: 姓 名:提交日期:2011年11月实验二 Linux进程创建与进程通信 [实验目的 1. 熟悉 ...

  2. 操作系统实验报告linux进程管理,计算机操作系统实验报告三Linux进程基本管理.doc...

    GDOU-B-11-112广东海洋大学学生实验报告书(学生用表) GDOU-B-11-112 实验名称 Linux进程基本管理 课程名称 计算机操作系统 课程号 学院(系) 专业 统 班级 学生姓名 ...

  3. c语言进程控制实验报告,操作系统进程的创建与控制实验报告.doc

    操作系统实验报告 实验一 进程的创建和控制 班 级: 12计算机12班 学 号: 127401219 姓 名: 刘艳仙 成 绩: 2013年 实验目的 1.掌握进程的概念,明确进程的含义 2.复习C语 ...

  4. 实验报告Linux操作系统基本命令,linux操作系统实验报告全部.doc

    linux操作系统实验报告全部 计算机操作系统 实验报告 学 号:姓 名:提交日期:2014.12.15成 绩: 东北大学秦皇岛分校 [实验题目]熟悉Linux/UNIX操作系统[实验目的]1.熟悉L ...

  5. 操作系统实验报告17:请求页面置换算法

    操作系统实验报告17 实验内容 实验内容:虚拟存储管理. 编写一个 C 程序模拟实现课件 Lecture24 中的请求页面置换算法 包括FIFO.LRU (stack and matrix imple ...

  6. 操作系统实验报告16:CPU 调度

    操作系统实验报告16 实验内容 实验内容:CPU 调度. 讨论课件 Lecture19-20 中 CPU 调度算法的例子,尝试基于 POSIX API 设计一个简单调度器(不考虑资源竞争问题): 创建 ...

  7. 操作系统实验报告15:进程同步与互斥线程池

    操作系统实验报告15 实验内容 实验内容:进程同步. 内容1:编译运行课件 Lecture18 例程代码. Algorithms 18-1 ~ 18-9. 内容2:在 Lab Week 13 的基础上 ...

  8. 操作系统实验报告14:Peterson 算法

    操作系统实验报告14 实验内容 实验内容:Peterson 算法. 把 Lecture08 示例 alg.8-1~8-3 拓展到多个读线程和多个写线程,应用 Peterson 算法原理设计实现共享内存 ...

  9. 操作系统实验报告13:线程池简单实现

    操作系统实验报告13 实验内容 实验内容:设计实现一个线程池 (Thread Pool) 使用 Pthread API FIFO 先不考虑互斥问题 编译.运行.测试用例 实验环境 架构:Intel x ...

最新文章

  1. 公司施行OKR了,绩效考核咋办?
  2. android service是单例么,android 使用单例还是service?
  3. c#获取对象的唯一标识_C#如何获取机器唯一标识符
  4. tomcat的三种部署方式
  5. java设置窗口不可移动_Java – JDialog不可移动
  6. Discuz 升级X3问题汇总整理
  7. 详解string容器(应用+模拟实现,string练习题)
  8. java循环遍历类属性_java循环遍历类属性 get 和set值方法
  9. C++ 沉思录——Chap4:设计类的核查表
  10. Remember The Word-Trie
  11. systemd和sysv服务管理和配置
  12. Android学习笔记(一)——Android应用的界面编程
  13. 有的浏览器可以直接打开rtsp,有的不能
  14. 5条线程轮流打印1~100
  15. idea中项目文件颜色含义
  16. 放弃腾讯75W年薪,回老家当公务员,提离职被领导教育。网友:leader嫉妒了
  17. Qt数据库应用11-通用数据生成器
  18. 反病毒工具-Wireshark
  19. vue 给某个div设置回到顶部
  20. 使用ros从realsence相机中获取图像

热门文章

  1. PHP获取文件后缀名
  2. 详解mysql int类型的长度值问题
  3. OCM备考 三. Managing Database Availability 之RMAN日常操作
  4. Win10安装后必做的优化,解决磁盘100%占用
  5. Visual Studio 2008中常用快捷键
  6. WPF IP地址输入控件的实现
  7. 解决SecureCRT中文版数据库里没找到防火墙'无'的错误提示
  8. SVN - 简单使用手册
  9. FJUT寒假第一周作业浮点数查寻题解
  10. GIS数据格式整理之Coverage篇