当前位置: 首页 > wzjs >正文

做酒店网站所用到的算法品牌营销公司

做酒店网站所用到的算法,品牌营销公司,服装企业网站建设策划书,湖南网页制作公司一:进程程序替换 1. 一旦程序替换成功,就去执行新代码了,原始代码的后半部分已经不存在了 2. exec*系列的函数,没有成功返回值,只有失败返回值-1 在程序替换的过程中,并没有创建新的进程,只是…

一:进程程序替换

1.  一旦程序替换成功,就去执行新代码了,原始代码的后半部分已经不存在了

2. exec*系列的函数,没有成功返回值,只有失败返回值-1

在程序替换的过程中,并没有创建新的进程,只是把当前进程的代码和数据用新的程序的代码和数据覆盖式的进行替换

1-1 execl

在Linux系统里,execl的一个系统调用函数,其作用是进程的程序替换

函数原型

#include<unistd.h>

int execl(const char* path,const char* arg,...)

  • path:此参数为一个字符串指针,指向要执行的程序(命令)的完整路径。例如usr/bin/ls就代表ls命令的可执行文件完整路径
  • arg:这是传给新程序的第一个参数,一般是程序(命令)自身的名称
  • ...:这是可变参数列表,用来传递参数给新程序。参数列表的最后必须以NULL结尾,从而表明参数传递结束。

 #include<stdio.h>#include<unistd.h>int main(){printf("我的程序要运行了\n");execl("/usr/bin/ls","ls","-l","-a",NULL);printf("我的程序运行完毕了\n");return 0;}

如上面代码所示, execl函数尝试执行/usr/bin/ls程序,并且传递了三个参数ls(程序本身),-l(用于显示详细信息),-a(显示全部信息),参数列表以NULL为结尾。若execl调用成功,当前进程就会被ls -l -a命令替换,从而显示当前目录下所有文件的详细信息。execl("/usr/bin/ls","ls","-l","-a",NULL);这条命令相当于先找到ls命令的路径,然后我们在终端输入的ls -l -a命令以逗号传递给每一个参数。我们可以看到下图中执行完ls -l -a将所有文件的详细信息打印后,后面没有打印 “我的程序运行完毕了”  这条语句,这是因为程序一旦替换成功就不再执行后序代码了,所以就没有打印

如下面代码所示,当我们将ls命令的路径和参数都传错时,execl进程的程序替换就会失败,我们用变量n来接收返回值,然后打印n的值,如下图所示,n的值为-1

 #include<stdio.h>#include<unistd.h>int main(){printf("我的程序要运行了\n");int n = execl("/usr/bn/ls","aa","-l","-a",NULL);printf("我的程序运行完毕了,%d\n",n);return 0;}

在上面我们讲到在程序替换过程中没有创建新进程,如何验证呢?如下面代码所示,在proc.c代码中,我们创建一个子进程并在其中打印子进程的进程ID并用execl将当前目录下的可执行文件other,传递other给新程序实现进程替换。而在other.cc代码中打印其进程ID

proc.c代码:

  1 #include<stdio.h>2 #include<unistd.h>3 #include<sys/types.h>4 #include<sys/wait.h>5 #include<stdlib.h>6 7 int main()8 {9     printf("我的程序要运行了\n");10     if(fork() == 0)11     {12         printf("I am Child,My Pid Is:%d\n",getpid());13         sleep(1);14         //execl("/usr/bin/ls","ls","-l","-a",NULL);15         execl("./other","other",NULL);16         exit(1);17     }18     waitpid(-1,NULL,0);19     printf("我的程序运行完毕了\n");20     return 0;21 }

other.cc代码: 

  1 #include<iostream>2 #include<unistd.h>3 4 int main()5 {6     std::cout << "hello C++,My Pid Is:" << getpid() << std::endl;7 8     return 0;9 }

 由下图可见,两个代码的PID一样说明execl实现进程替换过程中没有创建新程序

1-2 execlp

函数原型:

#include<unistd.h>

int execlp(const char* file,const char* arg,...);

execlp中的p相当于PATH,因此execlp会自动在环境变量PATH中查找指定的命令,这意味着我们在使用这个函数时不需要将程序的路径传递给函数,只需要写需要执行的文件名即可

  1 #include<stdio.h>2 #include<unistd.h>3 #include<sys/types.h>4 #include<sys/wait.h>5 #include<stdlib.h>6 7 int main()8 {9     printf("我的程序要运行了\n");10     if(fork() == 0)11     {12         printf("I am Child,My Pid Is:%d\n",getpid());13         sleep(1);14         execlp("ls","ls","-l","-a",NULL);15  16         exit(1);17     }18     waitpid(-1,NULL,0);19    printf("我的程序运行完毕了\n");20     return 0;21 }

如上代码所示,在子进程中执行execlp函数,执行ls -l -a命令,第一个参数为ls,因此系统会在PATH环境变量中搜索ls命令,后面的ls -l -a代表将当前目录下的所有文件的详细信息打印打印出来

1-3 execv

函数原型:

#include<unistd.h>

int execv(const char* path,char* const argv[]);

execv中的v可以理解为vector,相当于一个数组,参数path代表要执行的程序(命令)的完整路径,argv即提供一个命令行参数表(指针数组)

  1 #include<stdio.h>2 #include<unistd.h>3 #include<sys/types.h>4 #include<sys/wait.h>5 #include<stdlib.h>6 7 int main()8 {9     printf("我的程序要运行了\n");10     if(fork() == 0)11     {12         printf("I am Child,My Pid Is:%d\n",getpid());13         sleep(1);14         char* const argv[] = {15             (char* const)"ls",16             (char* const)"-l",17             (char* const)"-a",18             NULL,19         };  20         21         execv("/usr/bin/ls",argv);22         23     }24     waitpid(-1,NULL,0);25     printf("我的程序运行完毕了\n");26     return 0;27 }

如上代码所示,在子进程中,我们定义了一个指向char*的常量数组,数组变量分别为ls -l -a和NULL(表明结束),然后调用execv函数,在/usr/bin/ls目录下查找ls命令并执行ls命令,将argv数组传递给该命令

1-4 execvp

函数原型:

#include<unistd.h>

int execvp(const char* file,char* const argv[]);

execvp中的v代表传递一个指针数组给程序而不用传递参数列表,p代表PATH,因此不用写完整的路径。参数file要执行的程序名,argv传递给程序的参数数组

  1 #include<stdio.h>2 #include<unistd.h>3 #include<sys/types.h>4 #include<sys/wait.h>5 #include<stdlib.h>6 7 int main()8 {9     printf("我的程序要运行了\n");10     if(fork() == 0)11     {12         printf("I am Child,My Pid Is:%d\n",getpid());13         sleep(1);14         char* const argv[] = {15             (char* const)"ls",16             (char* const)"-l",17             (char* const)"-a",18             NULL,19         };20         execvp(argv[0],argv);21         22     }23     waitpid(-1,NULL,0);24     printf("我的程序运行完毕了\n");25     return 0;26 }

如上代码所示:在子进程中,定义了一个参数数组argv,包含命令名ls和选项-l、-a,以NULL结尾,execvp函数根据argv[0](即ls)在环境变量PATH中查找ls可执行文件并执行该文件,同时将argv作为参数传递给它

二:自定义XShell代码

  1 #include<iostream>2 #include<cstdio>3 #include<cstring>4 #include<cstdlib>5 #include<unistd.h>6 #include<sys/types.h>7 #include<sys/wait.h>8 9 #define COMMAND_SIZE 102410 #define FORMAT "[%s@%s %s]# "11 #define MAXARGC 12812 13 char* g_argv[MAXARGC];14 int g_argc = 0;15 16 char cwd[1024];17 char cwdenv[1024];18 19 //最新退出码20 int lastcode = 0;21 22 const char* GetUserName()23 {24     const char* name = getenv("USER");25     return name == NULL ? "None" : name;26 }27 28 const char* GetHostName()29 {30     const char* hostname = getenv("HOSTNAME");31     return hostname == NULL ? "None" : hostname;32 }33 34 const char* GetPwd()35 {36     //const char* pwd = getenv("PWD");37     const char* pwd = getcwd(cwd,sizeof(cwd));38     if(pwd != NULL)39     {40         snprintf(cwdenv,sizeof(cwdenv),"PWD=%s",cwd);41         putenv(cwdenv);42     }43     return pwd == NULL ? "None" : pwd;44 }45 46 const char* GetHome()47 {48     const char* home = getenv("HOME");49     return home == NULL ? "" : home;50 }51 52 // / /a/b/c路径获取切分53 std::string DirName(const char* pwd)54 {55     #define SLASH "/"56     std::string dir = pwd;57     if(dir == SLASH)58     {59         return "/";60     }61     auto pos = dir.rfind(SLASH);62     if(pos == std::string::npos)63         return "BUG?";64     return dir.substr(pos + 1);65 }66 67 68 void MakeCommandline(char cmd_prompt[],int size)69 {70 71     //snprintf(cmd_prompt,size,FORMAT,GetUserName(),GetHostName(),GetPwd());72     snprintf(cmd_prompt,size,FORMAT,GetUserName(),GetHostName(),DirName(GetPwd()).c_str());73 }74 75 //1.输出命令行提示符76 void PrintCommandline()77 {78     char prompt[COMMAND_SIZE];79     MakeCommandline(prompt,sizeof(prompt));80     printf("%s",prompt);81     fflush(stdout);82 }83 84 //2、获取命令行85 bool GetCommandline(char* out,int size)86 {87     //ls -a -l => "ls -a -l"88     char* c = fgets(out,size,stdin);89     if(c == NULL)90         return false;91     out[strlen(out) - 1] = 0;//清楚\n92     if(strlen(out) == 0)93         return false;94     return true;95 }96 97 //3.命令行分析98 bool ParseCommandline(char* commandline)99 {
100     #define SEP " "
101     g_argc = 0;
102     g_argv[g_argc++] = strtok(commandline,SEP);
103     while((bool)(g_argv[g_argc++] = strtok(nullptr,SEP)));
104     g_argc--;
105     return g_argc > 0 ? true : false;
106 }
107 
108 //4、检查并执行内建命令
109 bool CheckAndExecBuiltin()
110 {
111     std::string cmd = g_argv[0];
112     if(cmd == "cd")
113     {
114         //cd
115         if(g_argc == 1)
116         {
117             std::string home = GetHome();
118             if(home.empty())
119             {
120                 return true;
121             }
122             chdir(home.c_str());
123         }
124         else
125         {
126             //cd ~
127             std::string where = g_argv[1];
128             if(where == "~")
129             {
130                 std::string home = GetHome();
131                 if(home.empty())
132                     return true;
133                 chdir(home.c_str());
134             }
135             else
136             {
137                 //cd /home/
138                 std::string where = g_argv[1];
139                 chdir(where.c_str());
140             }
141         }
142         return true;
143     }
144     else if(cmd == "echo")
145     {
146         if(g_argc == 2)
147         {
148             //echo "hello world"
149             //echo $?
150             //echo $PATH
151             std::string opt = g_argv[1];
152             if(opt == "$?")
153             {
154                 std::cout << lastcode << std::endl;
155                 lastcode = 0;
156                 return true;
157             }
158         }
159     }
160     return false;
161 }
162 //5、执行命令
163 int Execute()
164 {
165     pid_t id = fork();
166 
167     if(id == 0)
168     {
169         //child
170         execvp(g_argv[0],g_argv);
171         exit(1);
172     }
173 
174     //father
175     int status = 0;
176     pid_t rid = waitpid(id,&status,0);
177     if(rid > 0)
178     {
179         lastcode = WEXITSTATUS(status);
180     }
181     return 0;
182 }
183 
184 void PrintArgv()
185 {
186     for(int i = 0;g_argv[i];i++)
187     {
188         printf("argv[%d]->%s\n",i,g_argv[i]);
189     }
190     printf("argc:%d\n",g_argc);
191 }
192 
193 int main()
194 {
195     while(1)
196     {
197         //1.输出命令行提示符
198         PrintCommandline();
199         char commandline[COMMAND_SIZE];
200         //2.获取命令行
201         if(!GetCommandline(commandline,sizeof(commandline)))
202             continue;
203         //printf("echo %s\n",commandline);
204 
205         //3.命令行分析 "ls -a l" => "ls" "-a" "-l"
206         if(!ParseCommandline(commandline))
207             continue;
208         //PrintArgv();
209 
210         //4、检查并处理内建命令
211         if(CheckAndExecBuiltin())
212             continue;
213 
214         //5、执行命令
215         Execute();
216     }
217     return 0;
218 }

http://www.dtcms.com/wzjs/119917.html

相关文章:

  • 不参与网站建设的弊端安装百度
  • 我要做网站t和p在一起怎么做网站
  • 专题网站建设策划seo整站优化
  • 西安网站建设ipv6电商平台哪个最好最可靠
  • 网站开发网页设计游戏设计互联网营销的优势
  • 什么网站能赚钱谷歌推广公司
  • 北京公司公示在哪个网站美食软文300范例
  • 做网站找我图片郑州seo哪家专业
  • 杭州拱墅区网站建设阿里云免费建站
  • 网站做多长时间才会成功营销技巧在线完整免费观看
  • 一些免费的网站福州短视频seo网站
  • 自己做文字壁纸的网站网络运营推广
  • 空投糖果网站开发推广链接让别人点击
  • 怎样把网站做的漂亮企拓客软件怎么样
  • 武汉做网站好的公司网店代运营和推广销售
  • 网站源码怎么预览iis搭建网站
  • 网站工作室西安seo按天收费
  • 网站登录页面怎么做的微信营销模式
  • 吴桥网站建设全案网络推广公司
  • 织梦零基础做网站站长网站统计
  • 高校网站建设工作总结海阳seo排名
  • 网站建设怎么制作模板惠州seo外包公司
  • 规划排版网站电商seo是什么意思
  • 南昌网站seo 优帮云电商营销推广方法
  • 建网站哪家好百度搜索关键词排行榜
  • 做企业公司网站中国疫情最新数据
  • 建筑师证报考条件seo课程简介
  • 吕梁网站制作seo网站推广与优化方案
  • 中国建设银行北京分行门户网站公告永久免费客服系统有哪些软件
  • 动态网站开发语言最流行的说哪种电子商务推广方式