兰州大学操作系统实验五进程管理题目和答案Word文档下载推荐.docx

上传人:b****6 文档编号:20066126 上传时间:2023-01-16 格式:DOCX 页数:37 大小:958.93KB
下载 相关 举报
兰州大学操作系统实验五进程管理题目和答案Word文档下载推荐.docx_第1页
第1页 / 共37页
兰州大学操作系统实验五进程管理题目和答案Word文档下载推荐.docx_第2页
第2页 / 共37页
兰州大学操作系统实验五进程管理题目和答案Word文档下载推荐.docx_第3页
第3页 / 共37页
兰州大学操作系统实验五进程管理题目和答案Word文档下载推荐.docx_第4页
第4页 / 共37页
兰州大学操作系统实验五进程管理题目和答案Word文档下载推荐.docx_第5页
第5页 / 共37页
点击查看更多>>
下载资源
资源描述

兰州大学操作系统实验五进程管理题目和答案Word文档下载推荐.docx

《兰州大学操作系统实验五进程管理题目和答案Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《兰州大学操作系统实验五进程管理题目和答案Word文档下载推荐.docx(37页珍藏版)》请在冰豆网上搜索。

兰州大学操作系统实验五进程管理题目和答案Word文档下载推荐.docx

ls-l/usr/bin/passwd

函数说明getegid()用来取得执行目前进程有效(effective)组ID。

有效的组ID用来决定进程执行时组的权限。

返回值返回有效的组ID。

Group组

1.4geteuid(取得有效的用户ID)

定义函数uid_tgeteuid(void)

函数说明geteuid()用来取得执行目前进程有效的用户ID。

有效的用户ID用来决定进程执行的权限,借由此改变此值,进程可以获得额外的权限。

倘若执行文件的setID位已被设置,该文件执行时,其进程的euid值便会设成该文件所有者的uid。

返回值返回有效的用户ID。

1.5getgid(取得真实的组ID)

定义函数gid_tgetgid(void);

函数说明getgid()用来取得执行目前进程的组ID。

返回值返回组ID

1.6getuid(取得真实的用户ID)

定义函数uid_tgetuid(void);

函数说明getuid()用来取得执行目前进程的用户ID。

返回值用户ID

1.7times(取得进程相关的时间)断异常

sys/times.h>

定义函数clock_ttimes(structtms*buf);

函数说明取得进程运行相关的时间。

参数说明

/*sys/times.h*/

structtms{

clock_ttms_utime;

/*进程花在执行用户模式代码上的时间*/<

=几十毫秒

clock_ttms_stime;

/*进程花在执行内核代码上的时间*/<

clock_ttms_cutime;

/*子进程花在执行用户模式代码上的时间*/

clock_ttms_cstime;

/*子进程花在执行内核代码上的时间*/

}

返回值自系统自举后经过的时钟嘀嗒数。

注意时钟嘀嗒数time转换为用户可读的方式,即多少秒,需通过如下方式:

(float)time/sysconf(_SC_CLK_TCK);

sysconf:

宏代表一常量

2.进程创建

2.1system(执行shell命令)通过执行命令产生一个进程

stdlib.h>

定义函数intsystem(constchar*string);

mansh-c(不覆盖现有的文件“>

”。

函数说明system()会调用fork()产生子进程,由子进程来调用/bin/sh-cstring来执行参数string字符串所代表的命令,此命令执行完后随即返回原调用的进程。

返回值如果system()在调用/bin/sh时失败则返回127,其他失败原因返回-1。

若参数string为空指针(NULL),则返回非零值。

2.2fork(建立一个新的进程)创建一个新的与父进程一模一样的子进程

定义函数pid_tfork(void);

函数说明fork()会产生一个新的子进程,其子进程会复制父进程的数据与堆栈空间,并继承父进程的用户代码,组代码,环境变量、已打开的文件代码、工作目录和资源限制等。

Linux使用copy-on-write(COW)技术,只有当其中一进程试图修改欲复制的空间时才会做真正的复制动作,由于这些继承的信息是复制而来,并非指相同的内存空间,因此子进程对这些变量的修改和父进程并不会同步。

此外,子进程不会继承父进程的文件锁定和未处理的信号。

注意Linux不保证子进程会比父进程先执行或晚执行,因此编写程序时要留意死锁或竞争条件的发生。

返回值如果fork()成功则在父进程会返回新建立的子进程代码(PID),而在新建立的子进程中则返回0。

如果fork失败则直接返回-1,失败原因存于errno中。

错误代码EAGAIN内存不足。

ENOMEM内存不足,无法配置核心所需的数据结构空间。

exec函数簇

2.3.1execl(执行文件)

定义函数intexecl(constchar*path,constchar*arg,....);

函数说明execl()用来执行参数path字符串所代表的文件路径,接下来的参数代表执行该文件时传递过去的argv(0)、argv[1]……,最后一个参数必须用空指针(NULL)作结束。

返回值如果执行成功则函数不会返回,执行失败则直接返回-1,失败原因存于errno中。

范例#include<

main()

{

printf(“BEFORE”);

execl(“/bin/ls”,”ls”,”-al”,”/etc/passwd”,(char*)0);

printf(“AFTER”);

//这里的东西被前面覆盖了,被回收了。

2.3.2execlp(从PATH环境变量中查找文件并执行)

定义函数intexeclp(constchar*file,constchar*arg,……);

函数说明execlp()会从PATH环境变量所指的目录中查找符合参数file的文件名,找到后便执行该文件,然后将第二个以后的参数当做该文件的argv[0]、argv[1]……,最后一个参数必须用空指针(NULL)作结束。

返回值如果执行成功则函数不会返回,执行失败则直接返回-1,失败原因存于errno中。

错误代码参考execve()。

范例/*执行ls-al/etc/passwdexeclp()会依PATH变量中的/bin找到/bin/ls*/

execlp(“ls”,”ls”,”-al”,”/etc/passwd”,(char*)0);

2.3.3execv(执行文件)

定义函数intexecv(constchar*path,char*constargv[]);

函数说明execv()用来执行参数path字符串所代表的文件路径,与execl()不同的地方在于execve()只需两个参数,第二个参数利用数组指针来传递给执行文件。

范例/*执行/bin/ls-al/etc/passwd*/

char*argv[]={“ls”,”-al”,”/etc/passwd”,(char*)0};

execv(“/bin/ls”,argv);

2.3.4execve(执行文件)

定义函数intexecve(constchar*filename,char*constargv[],char*constenvp[]);

函数说明execve()用来执行参数filename字符串所代表的文件路径,第二个参数系利用数组指针来传递给执行文件,最后一个参数则为传递给执行文件的新环境变量数组。

错误代码EACCES

1.欲执行的文件不具有用户可执行的权限。

2.欲执行的文件所属的文件系统是以noexec方式挂上。

3.欲执行的文件或script翻译器非一般文件。

EPERM

1.进程处于被追踪模式,执行者并不具有root权限,欲执行的文件具有SUID或SGID位。

2.欲执行的文件所属的文件系统是以nosuid方式挂上,欲执行的文件具有SUID或SGID位元,但执行者并不具有root权限。

E2BIG参数数组过大

ENOEXEC无法判断欲执行文件的执行文件格式,有可能是格式错误或无法在此平台执行。

EFAULT参数filename所指的字符串地址超出可存取空间范围。

ENAMETOOLONG参数filename所指的字符串太长。

ENOENT参数filename字符串所指定的文件不存在。

ENOMEM核心内存不足

ENOTDIR参数filename字符串所包含的目录路径并非有效目录

EACCES参数filename字符串所包含的目录路径无法存取,权限不足

ELOOP过多的符号连接

ETXTBUSY欲执行的文件已被其他进程打开而且正把数据写入该文件中

EIOI/O存取错误

ENFILE已达到系统所允许的打开文件总数。

EMFILE已达到系统所允许单一进程所能打开的文件总数。

EINVAL欲执行文件的ELF执行格式不只一个PT_INTERP节区

EISDIRELF翻译器为一目录

ELIBBADELF翻译器有问题。

char*argv[]={“ls”,”-al”,”/etc/passwd”,(char*)0};

char*envp[]={“PATH=/bin”,0}

execve(“/bin/ls”,argv,envp);

2.3.5execvp(执行文件)

定义函数intexecvp(constchar*file,char*constargv[]);

函数说明execvp()会从PATH环境变量所指的目录中查找符合参数file的文件名,找到后便执行该文件,然后将第二个参数argv传给该欲执行的文件。

范例/*请与execlp()范例对照*/

char*argv[]={“ls”,”-al”,”/etc/passwd”,0};

execvp(“ls”,argv);

3.进程等待find查找文件group查找字符串

3.1wait(等待子进程中断或结束)

sys/wait.h>

定义函数pid_twait(int*status);

函数说明wait()会暂时停止目前进程的执行,直到有信号来到或子进程结束。

如果在调用wait()时子进程已经结束,则wait()会立即返回子进程结束状态值。

子进程的结束状态值会由参数status返回,而子进程的进程ID也会一快返回。

如果不在意结束状态值,则参数status可以设成NULL。

子进程的结束状态值请参考waitpid()。

返回值如果执行成功则返回子进程ID(PID),如果有错误发生则返回-1。

失败原因存于errno中。

附加说明

pid_tpid;

intstatus,i;

if(fork()==0){//子进程代码

printf(“Thisisthechildprocess.pid=%d\n”,getpid());

exit(5);

}else{//父进程代码

sleep

(1);

printf(“Thisistheparentprocess,waitforchild...\n”;

pid=wait(&

status);

//等待

i=WEXITSTATUS(status);

//唤醒遗言放在status中

printf(“child’spid=%d.exitstatus=^d\n”,pid,i);

3.2waitpid(等待子进程中断或结束)

定义函数pid_twaitpid(pid_tpid,int*status,intoptions);

函数说明waitpid()会暂时停止目前进程的执行,直到有信号来到或子进程结束。

子进程的结束状态值会由参数status返回,而子进程的进程ID也会一快返回。

如果不在意结束状态值,则参数status可以设成NULL。

参数pid为欲等待的子进程ID,其他数值意义如下:

pid<

-1等待进程组ID为pid绝对值的任何子进程。

pid=-1等待任何子进程,相当于wait()。

pid=0等待进程组ID与目前进程相同的任何子进程。

pid>

0等待任何子进程ID为pid的子进程。

参数option可以为0或下面的OR组合:

WNOHANG如果没有任何已经结束的子进程则马上返回,不予以等待。

WUNTRACED如果子进程进入暂停执行情况则马上返回,但结束状态不予以理会。

子进程的结束状态返回后存于status,底下有几个宏可判别结束情况

WIFEXITED(status)如果子进程正常结束则为非0值。

WEXITSTATUS(status)取得子进程exit()返回的结束代码,一般会先用WIFEXITED来判断是否正常结束才能使用此宏。

WIFSIGNALED(status)如果子进程是因为信号而结束则此宏值为真

WTERMSIG(status)取得子进程因信号而中止的信号代码,一般会先用WIFSIGNALED来判断后才使用此宏。

WIFSTOPPED(status)如果子进程处于暂停执行情况则此宏值为真。

一般只有使用WUNTRACED时才会有此情况。

WSTOPSIG(status)取得引发子进程暂停的信号代码,一般会先用WIFSTOPPED来判断后才使用此宏。

4.信号

4.1kill(传送信号给指定的进程)

signal.h>

定义函数intkill(pid_tpid,intsig);

函数说明kill()可以用来送参数sig指定的信号给参数pid指定的进程。

参数pid有几种情况:

0将信号传给进程ID为pid的进程。

pid=0将信号传给和目前进程相同进程组的所有进程

pid=-1将信号广播传送给系统内所有的进程

0将信号传给进程组ID为pid绝对值的所有进程

返回值执行成功则返回0,如果有错误则返回-1。

错误代码EINVAL参数sig不合法

ESRCH参数pid所指定的进程或进程组不存在

EPERM权限不够无法传送信号给指定进程

intstatus;

if(!

(pid=fork())){

printf(“HiIamchildprocess!

\n”);

sleep(10);

return;

else{

printf(“sendsignaltochildprocess(%d)\n”,pid);

kill(pid,SIGABRT);

wait(&

if(WIFSIGNALED(status))

printf(“chileprocessreceivesignal%d\n”,WTERMSIG(status));

4.2signal(设置信号处理方式)

定义函数void(*signal(intsignum,void(*handler)(int)));

函数说明signal()会依参数signum指定的信号编号来设置该信号的处理函数。

当指定的信号到达时就会跳转到参数handler指定的函数执行。

如果参数handler不是函数指针,则必须是下列两个常数之一:

SIG_IGN忽略参数signum指定的信号。

SIG_DFL将参数signum指定的信号重设为核心预设的信号处理方式。

返回值返回先前的信号处理函数指针,如果有错误则返回SIG_ERR(-1)。

附加说明在信号发生跳转到自定的handler处理函数执行后,系统会自动将此处理函数换回原来系统预设的处理方式,如果要改变此操作请改用sigaction()。

5.进程调度

5.1getpriority(取得程序进程执行优先权)

sys/time.h>

sys/resource.h>

定义函数intgetpriority(intwhich,intwho);

函数说明getpriority()可用来取得进程、进程组和用户的进程执行优先权。

参数which有三种数值,参数who则依which值有不同定义

whichwho代表的意义

PRIO_PROCESSwho为进程ID

PRIO_PGRPwho为进程的组ID

PRIO_USERwho为用户ID

此函数返回的数值介于-20至20之间,代表进程执行优先权,数值越低代表有较高的优先次序,执行会较频繁。

返回值返回进程执行优先权,如有错误发生返回值则为-1且错误原因存于errno。

附加说明由于返回值有可能是-1,因此要同时检查errno是否存有错误原因。

最好在调用次函数前先清除errno变量。

错误代码ESRCH参数which或who可能有错,而找不到符合的进程。

EINVAL参数which值错误。

5.2setpriority(设置程序进程执行优先权)

定义函数intsetpriority(intwhich,intwho,intprio);

函数说明setpriority()可用来设置进程、进程组和用户的进程执行优先权。

参数which有三种数值,参数who则依which值有不同定义

参数prio介于-20至20之间。

代表进程执行优先权,数值越低代表有较高的优先次序,执行会较频繁。

此优先权默认是0,而只有超级用户(root)允许降低此值。

返回值执行成功则返回0,如果有错误发生返回值则为-1,错误原因存于errno。

ESRCH参数which或who可能有错,而找不到符合的进程

EINVAL参数which值错误。

EPERM权限不够,无法完成设置

EACCES一般用户无法降低优先权

5.3nice(改变进程优先顺序)

定义函数intnice(intinc);

函数说明nice()用来改变进程的进程执行优先顺序。

参数inc数值越大则优先顺序排在越后面,即表示进程执行会越慢。

只有超级用户才能使用负的inc值,代表优先顺序排在前面,进程执行会较快。

返回值如果执行成功则返回0,否则返回-1,失败原因存于errno中。

错误代码EPERM一般用户企图转用负的参数inc值改变进程优先顺序。

6.其他

6.1atexit(设置程序正常结束前调用的函数)

定义函数intatexit(void(*function)(void));

函数说明atexit()用来设置一个程序正常结束前调用的函数。

当程序通过调用exit()或从main中返回时,参数function所指定的函数会先被调用,然后才真正由exit()结束程序。

voidmy_exit(void)

printf(“beforeexit()!

atexit(my_exit);

exit(0);

6.2exit(正常结束进程)

定义函数voidexit(intstatus);

函数说明exit()用来正常终结目前进程的执行,并把参数status返回给父进程,而进程所有的缓冲区数据会自动写回并关闭未关闭的文件。

实验要求:

1.编写一个程序,打印进程的如下信息:

进程标识符,父进程标识符,真实用户ID,有效用户ID,真实用户组ID,有效用户组ID。

并分析真实用户ID和有效用户ID的区别。

2.阅读如下程序:

/*processusingtime*/

stdio.h>

time.h>

voidtime_print(char*,clock_t);

intmain(void)

clock_tstart,end;

structtmst_start,t_end;

start=times(&

t_start);

system(“grepthe/usr/doc/*/*>

/dev/null2>

/dev/nu

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 经管营销 > 金融投资

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1