1.系统调用是系统为用户程序调用操作系统所提供的子程序,属于特殊的原语。 2.进程同步和进程互斥是完全不相容的,因此不可能同时存在。
3.[1]指令用ASCII字符显示树状结构,清楚地表达系统中进程层次结构(宗族关系)。 4.Linux继承UNIX版本制定的规则,将Linux的版本分为内核版本和发行版本两类。
5.fork调用的一个奇妙之处就是它仅仅被调用一次,却能够返回两次,它可能有三种不同的返回值:
1、在父进程中,fork返回新创建子进程的进程ID; 2、在子进程中,fork返回0;
3、如果出现错误,fork返回一个负值。
6.信号只是用来通知某进程发生了什么事件,并不给该进程传递任何数据。
7.共享内存允许两个或多个进程共享一给定的存储区,因为数据不需要来回复制,所以是最快的一种进程间通信机制。
8.Linux命令的一般格式是( )。 A.命令名 [选项] [参数] B.[选项] [参数] 命令名 C.[参数] [选项] 命令名 D.[命令名] [选项] [参数]
9.将前一个命令的标准输出作为后一个命令的标准输入,称之为【1】 。 10.以下关Linux的叙述, 不正确的是( )。
A.Linux是一个可供多人使用的抢占式多任务操作系统。 B.Linux系统内核是由Linus Torvalds负责维护的。 C.Linux具有完备的网络能力。
D.Windows的程序可以在Linux运行,所以有很多的应用程序可供选择。
11.【fork】阅读下列代码。回答:变量c有3个备份,其值从小到大依次为[1],[2],[3]。 main(int argc, char ** argv) { int child = fork(); int c = 4;
if(child == 0) { c += 3 ; }
else { child = fork(); c += 5 ; if(child) c += 6 ; } }
12.【fork】请按注释提示填写代码。 #include
printf(\ exit(1); } strcpy(buf,\ if((cld_pid=fork())==0){ strcpy(buf,\ printf(\ printf(\ /*打印出本进程的ID*/ printf(\ /*打印出父进程的ID*/ write(fd,buf,strlen(buf)); close(fd); exit(0); }
else{ wait(0); printf(\
printf(\ /*打印出本进程的ID*/ printf(\ /*打印出子进程的ID*/ write([5],buf,strlen(buf)); close(fd); }
return 0; }
13.【信号】模拟闹钟:用fork( )创建子进程,子进程在等待5秒后用系统调用kill( )向父进程发送SIGALARM信号,父进程用系统调用signal( )捕捉SIGLARM信号。 #include
printf(\
if((pid = fork()) == 0){ //子进程5秒后发送信号SIGALRM给父进程 sleep(5);
kill(getppid(), SIGALRM); exit(0); }
//父进程安排好捕捉到SIGALRM信号后执行ding函数 printf(\ (void) signal(SIGALRM,ding);
//挂起父进程,直到有一个信号出现
pause();
if (alarm_fired) printf(\ printf(\
exit(0); }
14.【共享内存】试编写程序,实现父进程和子进程通过共享内存实现信息的交换。例如:子进程先将子进程号和父进程号写入共享内存,父进程将内容读出并显示。
#include
#define KEY 1234 /*键*/
#define SIZE 1024 /*欲建立的共享内存的大小*/ int main() { int shmid; char *shmaddr; char str[500]; struct shmid_ds buf;
shmid=shmget(KEY,SIZE,IPC_CREAT|0600); /*建立共享内存*/ if(shmid==-1) { printf(\ return 0; }
if(fork( )==0) { /*子进程*/ sleep(2);
shmaddr=(char*)shmget(shmid,NULL,0); /*系统自动选择一个地址连接*/ if(shmaddr==(void*)-1) { printf(\ return 0; } /*向共享内存内写数据*/ sprintf(str,\shared data from child process: \\nchild process ID %d;parent process ID %d.\\n\ strcpy(shmaddr,str);
shmdt(shmaddr); /*断开共享内存*/ exit(0); }
else { /*父进程*/ wait(0);
shmaddr=(char*)shmat(shmid,NULL,0); /*系统自动选择一个地址连接*/ if(shmaddr==(void*)-1) { printf(\ return 0; } printf(\ printf(\ shmdt(shmaddr); /*断开共享内存*/ /*当不再有任何其它进程使用该共享内存时系统将自动销毁它*/ shmctl(shmid,IPC_RMID,NULL); } }
15.【消息队列】发送者程序使用msgget创建一个消息队列;然后使用msgsnd函数向队列中添加消息。接收者使用msgget来获得消息队列标识符,并且接收消息,直到接收到特殊
消息“bye”。然后接收者使用msgctl删除消息队列进行一些清理工作。 #include
int main(){ int running =1 ; int msgid; struct my_msg_st some_data; long int msg_to_receive = 0; }
//首先,我们设置消息队列:
msgid =msgget((key_t)1234,0666|IPC_CREAT); if(msgid == -1){ fprintf(stderr,\ exit(EXIT_FAILURE); }
//然后,接收消息队列中的消息直到遇到一个bye消息。最后,消息队列被删除: while(running){ if(msgrcv(msgid, (void *)&some_data, BUFSIZ, msg_to_receive, 0) == -1){ fprintf(stderr, \ exit(EXIT_FAILURE); } printf(\ if(strncmp(some_data.some_text, \ running=0; } }
if(msgctl(msgid, IPC_RMID, 0)==-1) { fprintf(stderr, \ exit(EXIT_FAILURE); }
exit(EXIT_SUCCESS);
//发送程序与msg1.c类似。在main函数中,删除msg_to_receive声明,代之以buffer[BUFSIZ]。移除消息队列删除代码,并且在running循环中做出如下更改。现在我们调用msgsnd来将输入的文本发送到队列中。
#include
int main(){ int running = 1; struct my_msg_st some_data; int msgid; char buffer[BUFSIZ]; msgid = msgget((key_t)1234, 0666|IPC_CREAT); if(msgid==-1){ fprintf(stderr,\ } while(running){ printf(\ fgets(buffer, BUFSIZ, stdin); some_data.my_msg_type = 1; strcpy(some_data.some_text, buffer); if(msgsend(msgid, (void *)&some_data, MAX_TEXT, 0)==-1){ fprintf(stderr, \ exit(EXIT_FAILURE); } if(strncmp(buffer, \ } exit(EXIT_SUCCESS); } 16.【管道】建立一个pipe,同时父进程生成一个子进程,子进程先向pipe 写入一个字符串,然后父进程从pipe 中读取该字符串。 #include
pipe(fd); /*创建管道*/
while((x=[1]( ))==-1);/*创建子进程失败时,循环*/ if(x==0){ printf(\ \ scanf(\
fork(fd[1],buf,30);/*把buf 中字符写入管道*/ exit(0); } else{ write(0); read(fd[0],s,30);/*父进程读管道中字符*/ printf(\ } }
1.错 2.错 3.pstree 4.对 5.对 6.对 7.对 8.A 9.管道 10.D 11. 7 9 15