博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
mybash的编写与调试
阅读量:6909 次
发布时间:2019-06-27

本文共 3972 字,大约阅读时间需要 13 分钟。

fork()

  • 计算机程序设计中的分叉函数。返回值: 若成功调用一次则返回两个值,子进程返回0,父进程返回子进程标记;否则,出错返回-1。
    fork函数将运行着的程序分成2个(几乎)完全一样的进程,每个进程都启动一个从代码的同一位置开始执行的线程。这两个进程中的线程继续执行,就像是两个用户同时启动了该应用程序的两个副本。
mybash 版本一#include 
#include
#include
char command[256]; void main() { int rtn; /*子进程的返回数值*/ while(1) { printf( ">" ); gets( command, 256, stdin ); command[strlen(command)-1] = 0; if ( fork() == 0 ) { execlp( command, NULL ); perror( command ); exit( errno ); } else { wait ( &rtn ); printf( " child process return %d\n", rtn ); } }}

这个版本不能得到正确结果,会打印错误提示 ,但是可以根据运行结果的内容发现,fork()的返回值有两个,一个是0代表生成的子程序,还有一个代表的父程序。

exec( )函数族

  • 在Linux中要使用exec函数族。系统调用execve()对当前进程进行替换,替换者为一个指定的程序,其参数包括文件名(filename)、参数列表(argv)以及环境变量(envp)。exec函数族当然不止一个,但它们大致相同,在 Linux中,它们分别是:execl,execlp,execle,execv,execve和execvp,可以通过manexec命令来了解它们的具体情况。
  • 在这个函数族的函数使用的过程中主要是注意字符串数组的存放,目前看来所有的程序问题主要集中在这一部分,在这里先贴一个在网上查到的输入代码,之后再仔细研究
numargs=0;  while(numargs
0){ arglist[numargs]=NULL; execute(arglist); numargs=0; } } }

wait()

  • wait(等待子进程中断或结束)
    相关函数 waitpid,fork
    表头文件
#include
#include
pid_t wait (int * status);
  • 函数说明

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

束。如果在调用wait()时子进程已经结束,则wait()会立即返
回子进程结束状态值。子进程的结束状态值会由参数status 返回,
而子进程的进程识别码也会一快返回。如果不在意结束状态值,则
参数status 可以设成NULL。子进程的结束状态值请参考waitpid()。
返回值
如果执行成功则返回子进程识别码(PID),如果有错误发生则返回
-1。失败原因存于errno 中。

waitpid()

waitpid()会暂时停止目前进程的执行,直到有信号来到或子进程结束。waitpid的返回值比wait稍微复杂一些,一共有3种情况:

1.当正常返回的时候,waitpid返回收集到的子进程的进程ID;2.如果设置了选项WNOHANG,而调用中waitpid发现没有已退出的子进程可收集,则返回0;3.如果调用中出错,则返回-1,这时errno会被设置成相应的值以指示错误所在;当pid所指示的子进程不存在,或此进程存在,但不是调用进程的子进程,waitpid就会出错返回,这时errno被设置为ECHILD;

exit

  • exit()通常是用在子程序中用来终结程序用的,使用后程序自动结束,跳回操作系统。
  • exit(0) 表示程序正常退出,exit⑴/exit(-1)表示程序异常退出。
(1)exit和return 的区别: a.exit是一个函数,有参数。exit执行完后把控制权交给系统 b.return是函数执行完后的返回。renturn执行完后把控制权交给调用函数。 (2)exit和abort的区别: a.exit是正常终止进程 b.about是异常终止。

getpid()

getpid是一种函数,功能是取得进程识别码,许多程序利用取到的此值来建立临时文件,以避免临时文件相同带来的问题。通过在虚拟机中运行可以看出,getpid()的返回值每次都不一样。

getppid()

getpid返回当前进程标识,getppid返回父进程标识。

sleep()

函数功能: 执行挂起一段时间;

Sleep函数的一般形式:

Sleep(unsigned long);//参数即为挂起时间

pause()

alarm(time);执行之后告诉内核,让内核在time秒时间之后向该进程发送一个定时信号,然后该进程捕获该信号并处理;

pause()函数使该进程暂停让出CPU,但是该函数的暂停和前面的那个sleep函数的睡眠都是可被中断的睡眠,也就是说收到了中断信号之后再
重新执行该进程的时候就直接执行pause()和sleep()函数之后的语句;
可以用alarm()函数中断pause();

#include 
#include
#include
#include
void sig_handler(int num){ printf("receive the signal %d.\n", num); alarm(2);} int main(){ signal(SIGALRM, sig_handler);
alarm(2);
while(1){ pause(); printf("pause is over.\n"); } exit(0);}

1065404-20171029153742336-1192908341.png

setenv

函数说明 setenv()用来改变或增加环境变量的内容。参数name为环境变量名称字符串。参数 value则为变量内容,参数overwrite用来决定是否要改变已存在的环境变量。如果没有此环境变量则无论overwrite为何值均添加此环境变量。若环境变量存在,当overwrite不为0时,原内容会被改为参数value所指的变量内容;当overwrite为0时,则参数value会被忽略。返回值 执行成功则返回0,有错误发生时返回-1。

unsetenv

int unsetenv(const char *name);

删除name的定义,即使不存在也不算出错。
主要用于setenv()函数使用过后释放空间。

  • 伪代码

int main(){//从终端读取要执行的命令//fork()产生子进程执行此命令//如果exec函数返回,表明没有正常执行命令,打印错误信息perro()//父进程, 等待子进程结束,并打印子进程的返回值wait(&rtn) }
  • 产品代码

#include 
#include
#include
#include
#include
void main(){ char *command[3]; command[0] = "ls"; command[1] = "-l"; command[2] = 0; int s,i=0; int rtn; printf( ">" ); //printf("%s %s %s",command[1],command[2],command[3]); printf("%s",command[0]); i=0; s=fork(); if ( s== 0 ) { //printf("%d\n",s); execvp( command[0], command ); //perror( command ); exit( errno ); } else { //printf("%d\n",s); wait ( &rtn ); printf( " child process return %d\n", rtn ); } }
  • 后续修改

参考教材第八章parseline等关于输入字符串的代码,问题得到了解决。

1065404-20171028183244680-316691675.png

注:show为 2进制可执行文件,所以显示乱码。

参考资料

转载于:https://www.cnblogs.com/xhwh/p/7711090.html

你可能感兴趣的文章
c#中转义符总结
查看>>
Android学习笔记之AndroidManifest.xml文件解析(转载)
查看>>
网络干货,无论是运维还是开发都要知道的网络知识系列之(五)
查看>>
MySQL查询及删除重复记录的方法
查看>>
.net微信公众号开发——快速入门
查看>>
ASP.NET Core 数据保护(Data Protection 集群场景)【下】
查看>>
UML类图几种关系的总结,泛化 = 实现 > 组合 > 聚合 > 关联 > 依赖
查看>>
Intellij Idea 2016 配置Tomcat虚拟目录
查看>>
Android 调整透明度的图片查看器
查看>>
一个开源的仓储系统
查看>>
5.24 Declaring Attributes of Functions【转】
查看>>
利用SCORE法则来总结一次偷懒的单元测试过程
查看>>
angular中的 登录检查 和 过期Session清理
查看>>
基于FormsAuthentication的用户、角色身份认证
查看>>
阿里云-DRDS(转)
查看>>
Lua协程-测试3
查看>>
009-java中常用的单个键值对
查看>>
微软为AJAX和jQuery类库提供CDN服务
查看>>
LuoYun 开源云计算平台软件 0.2 Beta 版本发布 — LinuxTOY
查看>>
约会你的私人定制
查看>>