(1)运行→就绪,1种;
(2)创建→就绪,1种;
(3)运行→阻塞,3种;
(4)阻塞→就绪,3种;
(5)运行→终止,4种
答:
(1)调度器分配的时间片已被进程使用完
(2)进程fork()后
(3)进程进行系统服务请求(如I/O请求)
(4)进程进行系统服务请求已完成
(5)进程已结束正常返回,进程发生异常,收到终止信号
fork():创建一个PCB,进程状态变为就绪,加入该进程到就绪队列中
exit():删除该PCB释放资源,进程状态变为终止,将该进程从运行队列中删除
wait():进程状态变为阻塞,将该进程转移到阻塞队列
int main(){
if (fork() ==0){
printf ("A");
printf("B");
exit(0);
}
else{
if (fork() ==0){
printf ("C");
printf("D");
exit(0);
}
else{
printf ("E");
printf("F");
exit(0);
}
}
}
可能的输出序列:
ABCDEF
ABEFCD
CDEFAB
CDABEF
EFABCD
EFCDAB
ACDEFB
…
#include
#include
#include
#include
#include
using namespace std;
int main()
{
pid_t pid;
if ((pid = fork()) == 0) //创建Linux子进程
{
char* execv_str[] = {"ps", "-A",NULL};
if (execv("/usr/bin/ps", execv_str) < 0) //调用ps -A
{
perror("error on exec");
exit(-1);
}
exit(0);
}
else //父进程
{
wait(NULL);//等待子进程结束
cout<
运行结果:
pl: lam father process
p11: I am elder brother process
p12: I am young brother process
p121: I am eldergrandson process
pl22: I am younger grandson process
#include
#include
#include
#include
using namespace std;
int main()//p1
{
cout << "I am father process." << endl;
if (fork() == 0)//创建p11
{
cout << "I am elder brother process." << endl;
exit(0);
}
else
{
if (fork() == 0)//创建p12
{
cout << "I am young brother process." << endl;
if (fork() == 0)//创建p121
{
cout << "I am elder grandson process." << endl;
exit(0);
}
else
{
if (fork() == 0)//创建p122
{
cout << "I am young grandson process." << endl;
exit(0);
}
exit(0);
}
}
exit(0);
}
}
运行结果:
# include
int main
{
int 1;
fork();
i = fork();
if (i> 0)
fork();
if (i> 0)
fork();
printf("hello\n");
}
输出10行
#include "wrapper.h"
void callit()
{
fork();
printf("hello\m");
if(fork()>0)
exit(0);
else
printf("hello\n");
return;
}
int main()
{
callit();
printf("hello\n");
exit(0);
}
输出6行
#include"wrapper.h"
int main()
{
int x = 3;
if (fork() != 0)
printf("x=%d\n",++x);
printf("x=%d\n",--x);
return 0;
}
243、423、432
#include"wrapper.h"
void callit()
{
pid_t pid;
pid = fork();
if (pid == 0)
printf("hello\n");
return;
}
int main()
{
callit();
printf("hello\n");
exit(0);
}
输出3行
void callit()
{
int i;
for (i = 0; i < n; i++)
fork();
printf("hello\n");
exit(0);
}
行数 = 2 ^ n
int main
{
if (fork()==0){
printf("a");
printf("x");
}
else
if (fork()==0)
printf("b");
else
printf("c");
}
cbax、bcax、axbc、axcb、baxc、caxb、cabx、bacx、acxb、abxc、abcx、acbx
int main()
{
if(fork() == 0)
{
printf("A1\n");
printf("A2\n");
...
printf("An\n");
exit(0);
}
else
{
printf("B1\n");
printf("B2\n");
...
printf("Bn\n");
exit(0);
}
}
答案:
C m + n n C_{m+n}^{n} Cm+nn
答案:
C m + n + k k C m + n n C_{m+n+k}^{k}C_{m+n}^{n} Cm+n+kkCm+nn
void end(void) { printf("2"); }
int main()
{
if(fork() == 0)
atexit(end);
if(fork() == 0)
printf("0");
else
printf("1");
exit(0);
}
ACE
#include
#include
#include
#include
#include
#include
using namespace std;
void sigDo(int sig);//收到信号的行为
pid_t pid1; //子进程pid
pid_t pid2; //子进程pid
int main()
{
if ((pid1 = fork()) == 0) //创建第一个子进程
{
cout << "elder process is running!" << endl;
signal(SIGQUIT, SIG_IGN);//忽略SIGQUIT信号
signal(SIGSTKFLT, sigDo);//修改SIGSTKFLT信号(16)的行为
pause();
}
else
{
if ((pid2 = fork()) == 0) //创建第二个子进程
{
cout << "young process is running!" << endl;
signal(SIGQUIT, SIG_IGN);;//忽略SIGQUIT信号
signal(SIGCHLD, sigDo);//修改SIGCHLD信号(17)的行为
pause();
}
//修改信号SIGQUIT的行为
signal(SIGQUIT, [](int sig)->void
{
cout << "sent" << endl;
kill(pid1, SIGSTKFLT);
kill(pid2, SIGCHLD);
});
wait(NULL);//等待子进程结束
cout << "main exit" << endl;
exit(0);//主进程结束
}
}
void sigDo(int sig)
{
cout << sig << ": exit" << endl;
exit(0);
}
(1) abcdefghij或fghijabcde 子进程与父进程共享文件指针
(2) abcdeabcde 子进程与父进程不共享文件指针
(3) cdefgjklmnl或jklmnlcdefg 子进程与父进程共享文件指针,且调用了两次lseek()
int main()
{
int x = 10;
if(fork() == 0)
x = x + 20;
else{
x = x + 30;
if(fork() == 0)
x = x + 40;
else
x = x + 50;
}
printf("x=%d\n",x);
}
main:90
子1:30
子2:80
答:main进程创建子进程后,子进程将通过exec函数调用shell的ls指令,所以无论什么情况都无法到达printf(“LINE J”)代码行
int main()
{
pid_t pidj pidl:
pid = fork(); /* fork a child process */
if (pid < 0){ /* error occurred */
fprintf(stderr, "Fork Failed");
return 1;
}
else if (pid==0) { /* child process */
pid1 = getpid();
printf("Child: pid = %d",pid); /* A */
printft("Child: pidl = %d",pid1); /* B */
}
else { /* par«nr process •/
pid1= getpid();
printf("parant: pid = %d",pid); /* C */
printf("parent: pidl= %d",pidl); /* D */
wait(NULL);
}
return 0;
}
A = 0、B = 2603、C = 2603、D = 2600
x行输出依次为0,-1,-4,-9,-16
y行输出依次为0,1,2,3,4
子进程是父进程的副本,对子进程变量的修改不会影响到父进程
对于单核多任务处理机,仅存在并发,而无法存在并行。
@程序代码均使用Visual Studio 2019作为IDE,通过ssh连接ubuntu20.04使用g++9.3编译
12、13题抄答案的,希望能有大佬讲解一下。