目录
问题
实验示例代码中,调用execl()时,第二个传参为什么会是可执行程序名:
execl("/bin/ls", "ls", "-l", "-color", NULL)
- 猜测原因:可以更好地模拟在shell中执行时的传参,防止传参失效。
- 剖析:
- 我们先来看看 execl() 的定义:
- int execl( path, arg0[,arg1,...argn], NULL);
- char *path, *arg0, *arg1, ..., *argn
- path:(必须)可执行程序的路径(可以是相对路径,也可以是绝对路径)
- arg0, ... argn :(可选)可变参数数量,给这个可执行程序的传参(这些传参是传给可执行程序的main函数)
- NULL:(建议)最后需要一个NULL结尾,表示传参结束。
- 可见,按理从第二个参数开始,都是给可执行程序的传参,因此是不需要第二个参数给一个程序名的。
- 我们可以写一个hello来接收main函数的参数:hello.cpp
#include <iostream>
using namespace std;
int main(int aNum, char** aStr)
{
cout << "hello,coolight" << endl;
cout << "main参数列表:" << endl;
for(int i = 0; i < aNum; ++i)
cout << i + 1 << " : " << aStr[i] << endl;
return 0;
}
- -
- 编译生成 hello
- 然后在实验写的程序中使用execl调用这个 hello :
- execl("./hello", "hello", "-1", "-2", NULL);
- hello程序输出结果:
- 可以看到,第二个参数是程序名(“hello”)确实也是main函数的传参。
- 但是,为什么要这样做呢?
- 如果我们直接在shell运行hello,且不给它传参呢?
- shell执行:$ ./hello
- 运行结果:
- 可见,在shell中,即使只执行hello程序,它本身的文件名也会作为给main函数的第一个传参
- 那现在看来,答案似乎已经在我们面前了:
- 在程序中调用execl()时,第二个参数给了可执行程序名是为了更接近地模拟直接在shell中执行时的传参,防止有些程序会忽略main函数的第一个参数(在shell中运行时是可执行文件名),导致传参可能会失效。
实验具体内容
实验内容
- 用fork()创建一个进程,再调用exec()用新的程序替换该子进程的内容
- 利用wait()来控制进程执行顺序
涉及的系统调用
在Linux中fork()是一个非常有用的系统调用,但在Linux中建立进程除了fork()之外,也可用与fork() 配合使用的exec()。
exec()系列
- 系统调用exec( )系列,也可用于新程序的运行。fork( )只是将父进程的用户级上下文拷贝到新进程中,而exec( )系列可以将一个可执行的二进制文件覆盖在新进程的用户级上下文的存储空间上,以更改新进程的用户级上下文。exec( )系列中的系统调用都完成相同的功能,它们把一个新程序装入内存,来改变调用进程的执行代码,从而形成新进程。如果exec( )调用成功,调用进程将被覆盖,然后从新程序的入口开始执行,这样就产生了一个新进程,新进程的进程标识符id 与调用进程相同。
- exec( )没有建立一个与调用进程并发的子进程,而是用新进程取代了原来进程。所以exec( )调用成功后,没有任何数据返回,这与fork( )不同。exec( )系列系统调用在Linux系统库unistd.h中,共有execl、execlp、execle、execv、execvp五个,其基本功能相同,只是以不同的方式来给出参数。
- 一种是直接给出参数的指针,如:
- int execl(path,arg0[,arg1,...argn],0);
- char *path,*arg0,*arg1,...,*argn;
- 另一种是给出指向参数表的指针,如:
- int execv(path,argv);
- char *path,*argv[ ];
exec()和fork()联合使用
- 系统调用exec和fork( )联合使用能为程序开发提供有力支持。用fork( )建立子进程,然后在子进程中使用exec( ),这样就实现了父进程与一个与它完全不同子进程的并发执行。
- 一般,wait、exec联合使用的模型为:
int status;
............
if (fork() == 0)
{
............
execl(...);
............
}
wait(&status);
wait()
- 等待子进程运行结束。如果子进程没有完成,父进程一直等待。wait( )将调用进程挂起,直至其子进程因暂停或终止而发来软中断信号为止。如果在wait( )前已有子进程暂停或终止,则调用进程做适当处理后便返回。
- 系统调用格式:
- int wait(status)
- int *status;
- 其中,status是用户空间的地址。它的低8位反应子进程状态,为0表示子进程正常结束,非0则表示出现了各种各样的问题;高8位则带回了exit( )的返回值。exit( )返回值由系统给出。
- 核心对wait( )作以下处理:
- (1)首先查找调用进程是否有子进程,若无,则返回出错码;
- (2)若找到一处于“僵死状态”的子进程,则将子进程的执行时间加到父进程的执行时间上,并释放子进程的进程表项;
- (3)若未找到处于“僵死状态”的子进程,则调用进程便在可被中断的优先级上睡眠,等待其子进程发来软中断信号时被唤醒。
exit()
- 终止进程的执行。
- 系统调用格式:
- void exit(status)
- int status;
- 其中,status是返回给父进程的一个整数,以备查考。
- 为了及时回收进程所占用的资源并减少父进程的干预,Linux利用exit( )来实现进程的自我终止,通常父进程在创建子进程时,应在进程的末尾安排一条exit( ),使子进程自我终止。exit(0)表示进程正常终止,exit(1)表示进程运行有错,异常终止。
- 如果调用进程在执行exit( )时,其父进程正在等待它的终止,则父进程可立即得到其返回的整数。核心须为exit( )完成以下操作:
- (1)关闭软中断
- (2)回收资源
- (3)写记帐信息
- (4)置进程为“僵死状态”
源代码
- exec_main.cpp
#include <iostream>
#include <unistd.h>
#include "sys/wait.h"
#include "sys/types.h"
using namespace std;
int main()
{
cout << "<< coolgiht" << endl;
int status, renum_fork = fork();
if(renum_fork == -1){
cout << "<< fork error!" << endl;
}else if(renum_fork == 0){ //子进程
execl("./hello", "hello", "-1", "-2", NULL);
cout << "execl error!" << endl;
}else{ //父进程
wait(NULL);
cout << "<< 完成!" << endl;
}
return 0;
}
- hello.cpp
#include <iostream>
using namespace std;
int main(int aNum, char** aStr)
{
cout << "hello,coolight" << endl;
cout << "main参数列表:" << endl;
for(int i = 0; i < aNum; ++i)
cout << i + 1 << " : " << aStr[i] << endl;
return 0;
}
运行结果截图
思考
- 什么是进程同步?wait( )是如何实现进程同步的?
- 一组进程为了协调其推进速度,在某些地方需要相互等待或者唤醒,这种进程间的相互制约就被称作是进程同步。
- 当父进程调用wait()时,会阻塞等待一个子进程结束而发出信号,然后父进程才会继续运行。
buy cytotec pills online cheap cytotec pills buy online cytotec pills buy online
buy doxycycline monohydrate: buy doxycycline online – buy doxycycline cheap
buy cipro: antibiotics cipro – purchase cipro
Cytotec 200mcg price: cytotec abortion pill – Misoprostol 200 mg buy online
diflucan online canada diflucan 150 mg tablets buy diflucan online usa
cytotec buy online usa: order cytotec online – buy cytotec pills online cheap
buy doxycycline hyclate 100mg without a rx doxycycline 100mg doxycycline medication
https://diflucan.icu/# how can i get diflucan over the counter
Everything is very open with a really clear clarification of the challenges.
It was definitely informative. Your website is useful.
Thank you for sharing!
cipro ciprofloxacin: ciprofloxacin generic price – ciprofloxacin 500mg buy online
buy cytotec in usa: п»їcytotec pills online – order cytotec online
ciprofloxacin generic: ciprofloxacin 500 mg tablet price – ciprofloxacin 500 mg tablet price
buy cytotec: buy cytotec online fast delivery – buy cytotec over the counter
buy cytotec in usa purchase cytotec order cytotec online
antibiotics cipro: cipro for sale – buy cipro online without prescription
tamoxifen and ovarian cancer where to get nolvadex tamoxifen and uterine thickening
doxycycline hyclate 100 mg cap: buy cheap doxycycline online – buy doxycycline online 270 tabs
buy misoprostol over the counter: buy cytotec pills online cheap – buy misoprostol over the counter
doxycycline hyclate: doxycycline 200 mg – buy doxycycline hyclate 100mg without a rx
diflucan 100mg where to buy diflucan online how can i get diflucan over the counter
http://diflucan.icu/# diflucan in usa
buy diflucan 150mg: diflucan online purchase uk – diflucan from india
doxycycline vibramycin: doxycycline 150 mg – doxy 200
ciprofloxacin 500 mg tablet price antibiotics cipro cipro
buy ciprofloxacin over the counter: buy cipro cheap – cipro
buy doxycycline for dogs: generic doxycycline – doxycycline mono
diflucan 150 cost diflucan 1 pill diflucan usa
tamoxifen and depression: does tamoxifen cause weight loss – nolvadex gynecomastia
doxycycline 150 mg: buy doxycycline hyclate 100mg without a rx – order doxycycline online
diflucan drug diflucan 150 mg over the counter diflucan 200 mg daily
order cytotec online: buy cytotec online – Cytotec 200mcg price
https://misoprostol.top/# cytotec abortion pill
buy doxycycline: doxycycline 100 mg – where to get doxycycline
ciprofloxacin cipro pharmacy buy cipro cheap
order doxycycline online: buy doxycycline without prescription – doxycycline generic
ciprofloxacin: cipro generic – buy ciprofloxacin over the counter
over the counter diflucan pill: diflucan 200 mg price south africa – diflucan price south africa
buy doxycycline online without prescription buy doxycycline without prescription uk doxycycline vibramycin
Superb, what a web site it is! This weblog provides useful information to us,
keep it up.
buy cytotec in usa: buy cytotec over the counter – buy cytotec over the counter
buying from online mexican pharmacy mexican pharmacy reputable mexican pharmacies online
https://mexicanpharmgrx.com/# mexico drug stores pharmacies
online pharmacy india: indian pharmacy – п»їlegitimate online pharmacies india
buying from online mexican pharmacy online pharmacy in Mexico mexican border pharmacies shipping to usa
http://mexicanpharmgrx.com/# mexican rx online
ordering drugs from canada: Pharmacies in Canada that ship to the US – pharmacy canadian superstore
certified canadian international pharmacy: International Pharmacy delivery – best rated canadian pharmacy
http://mexicanpharmgrx.com/# mexico drug stores pharmacies
mexico drug stores pharmacies Pills from Mexican Pharmacy mexico drug stores pharmacies
canadian valley pharmacy: canadian pharmacy – canada discount pharmacy