8.9
進(jìn)程對(duì) |
并發(fā)? |
---|---|
AB |
否 |
AC |
是 |
AD |
是 |
BC |
是 |
BD |
是 |
CD |
是 |
8.10
A
fork
B
execve
笤成,longjmp
C
setjmp
8.11
4
8.12
8
8.13
x=4
x=3
x=2
8.14
3
8.15
5
8.16
counter = 2
8.17
三種可能性。
1
Hello
0
1
Bye
2
Bye
2
Hello
1
0
Bye
2
Bye
3
Hello
1
Bye
0
2
Bye
8.18
A,C,E
8.19
8.20
#include <unistd.h>
using namespace std;
int main(int argc, char* argv[], char* envp[])
{
execve("/bin/ls", argv, envp);
}
不明白意義何在眷茁,練習(xí)如何使用execve
么炕泳。。
8.21
abc
或bac
8.22
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
void unix_error(char* msg){
fprintf(stderr, "%s : %s\n", msg, strerror(errno));
}
pid_t Fork(){
pid_t pid;
if((pid = fork()) < 0)
unix_error("Fork error");
return pid;
}
int mysystem(char* command){
pid_t pid = Fork();
if(pid){
int status;
wait(&status);
if(WIFEXITED(status))
return WEXITSTATUS(status);
if(WIFSIGNALED(status))
return WTERMSIG(status);
}else{
char* argv[] = {"/bin/sh", "-c", command, NULL};
execve("/bin/sh", argv, NULL);
}
}
int main(int argc, char* argv[], char* envp[])
{
printf("exit code: %d\n", mysystem(argv[1]));
fflush(stdout);
}
mac上好像ctrl+c
無法觸發(fā)上祈,通過資源監(jiān)視器殺進(jìn)程可以觸發(fā)非正常退出的分支培遵。
8.23
信號(hào)量不會(huì)排隊(duì),當(dāng)子進(jìn)程給父進(jìn)程發(fā)送信號(hào)時(shí)登刺,第一個(gè)信號(hào)會(huì)被接受并且處理籽腕,第二個(gè)信號(hào)會(huì)被記錄并且等待第一個(gè)信號(hào)處理完成,其他的信號(hào)都會(huì)被簡(jiǎn)單地丟棄塘砸。
所以正如教材前面所說的,不能使用信號(hào)量對(duì)其他進(jìn)程中的某些東西計(jì)數(shù)晤锥。
8.24
#include "csapp.h"
#define N 2
int main(){
int status, i;
pid_t pid;
/* Parent creates N children */
for(i = 0; i < N; i++)
if((pid = Fork()) == 0){
int* p = 0x0;
*p = 1;
exit(0);
}
/* Parent reaps N children in no particular order */
while((pid = waitpid(-1, &status, 0)) > 0){
if(WIFEXITED(status))
printf("child %d terminated normally with exit status = %d\n", pid, WEXITSTATUS(status));
else if(WIFSIGNALED(status)){
Sio_puts("child ");
Sio_putl(pid);
psignal(SIGSEGV, " terminated by signal 11");
}
}
/* The only normal termination is if there are no more children */
if(errno != ECHILD)
unix_error("waitpid error");
exit(0);
}
運(yùn)行輸出:
child 42018 terminated by signal 11: Segmentation fault
child 42019 terminated by signal 11: Segmentation fault
一開始沒看懂題目意思掉蔬,看懂后閱讀psignal
相關(guān)資料就可以完成,注意使用printf
會(huì)出問題矾瘾,因?yàn)?code>printf并不是安全的女轿,這里使用的是Sioputs
和Sioputl
,也可以使用sprintf
先寫到緩沖區(qū)然后利用psignal
進(jìn)行輸出壕翩。
8.25
#include "csapp.h"
sigjmp_buf buf;
void sigchld_handler(int sig){
siglongjmp(buf, 1);
}
char* tfgets(char* str){
if(sigsetjmp(buf, 1))
return NULL;
pid_t pid;
if(signal(SIGCHLD, sigchld_handler) == SIG_ERR)
unix_error("set SIGCHLD error");
if((pid = Fork()) == 0){
sleep(5);
exit(0);
}else{
return gets(str);
}
}
int main(){
char buf[256];
puts(tfgets(buf));
}
首先得開一個(gè)子進(jìn)程對(duì)五秒時(shí)間進(jìn)行計(jì)數(shù)蛉迹,如果子進(jìn)程成功返回說明超時(shí)應(yīng)該返回NULL
,不然直接返回gets
的結(jié)果就行放妈。
所以父進(jìn)程應(yīng)該直接調(diào)用gets
滿足不超時(shí)的情況北救,問題在于超時(shí)后父進(jìn)程捕捉到子進(jìn)程結(jié)束時(shí)的仍在等待gets
荐操,而signal handler
只能返回到當(dāng)前指令無法對(duì)流程進(jìn)行控制,這時(shí)候就應(yīng)該使用非本地跳轉(zhuǎn)返回到注冊(cè)地進(jìn)行處理珍策。
理論上感覺goto
也是可以的托启,由于實(shí)用性不高沒有進(jìn)行嘗試。
8.26
其實(shí)就是shell lab
攘宙,等待完成中屯耸。