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

做返利网站如何操作搜索引擎培训班

做返利网站如何操作,搜索引擎培训班,郑州网络推广培训,旅游网站框架进程创建 在Linux中我们使用fork函数创建新进程: fork函数 fork函数是Linux中的一个系统调用,用于创建一个新的进程,创建的新进程是原来进程的子进程 返回值:如果子进程创建失败,返回值是-1。如果子进程创建成功&a…

进程创建

在Linux中我们使用fork函数创建新进程:

fork函数

fork函数是Linux中的一个系统调用,用于创建一个新的进程,创建的新进程是原来进程的子进程

返回值:如果子进程创建失败,返回值是-1。如果子进程创建成功,对于父进程而言,fork的返回值是子进程的pid(子进程的进程号);对于子进程而言,fork的返回值是0。

让父子进程分别打印fork函数的返回值和自己的PID:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>int main()
{pid_t pid;      //parent_idpid_t cid;      //child_pidprintf("Before fork Process id: %d\n", getpid());cid = fork();printf("After fork, Process id: %d\n", getpid());printf("fork_function return: %d\n", cid);sleep(5);return 0;
}

实验结果:

调用fork后,内核中的fork代码会执行:

• 分配新的内存块和内核数据结构给⼦进程

• 将⽗进程部分数据结构内容拷⻉⾄⼦进程

• 将⼦进程添加到系统进程列表当中

• fork返回,调度器开始调度

子进程被创建好后,父子进程会并发执行后续代码

父子进程内存空间独立

上文说到,fork函数会把父进程的代码和数据拷贝给子进程,以此来保证进程之间的独立性,但实际上,为了节省内存空间和提高运行效率,只有当子进程的代码和数据发生变化时,才会为子进程开辟一块内存空间,并将父进程的代码和数据拷贝给子进程,这被称为写时拷贝

而在写时拷贝之前,父子进程的虚拟地址相同,并且通过页表映射后指向同一处物理地址

而在写时拷贝之后,父子进程的虚拟地址仍然相同,只是会映射到不同的物理地址

进程终止

进程终⽌的本质是释放进程申请的相关内核数据结构和对应的数据和代码。

进程退出的三种情况:

1.代码运⾏完毕,结果正确

2.代码运⾏完毕,结果不正确

3. 代码异常终⽌

为了判断进程终止是哪种情况,进程在结束时会将退出码和退出信号返回给父进程,其中,退出信号用于判断进程是否异常,退出码用于判断进程运行结果是否正确

如何获取退出码和退出信号,我们在进程等待部分再做介绍,这里先介绍常见的退出码:

可以使⽤strerror函数来获取退出码对应的描述。

返回不同的退出码:

1.使用 return n

2.使用void exit(int status)或void _exit(int status),二者区别如下:

return n和exit(n)等效

进程等待

进程等待的目的:

1.检查子进程的任务执行

2.避免产生僵尸进程

进程等待的方法

wait函数

#include<sys/types.h>
#include<sys/wait.h>
pid_t wait(int* status);

返回值:

成功返回被等待进程 pid ,失败返回-1 。

参数:

status:输出型参数,获取⼦进程退出码 , 不关⼼则可以设置成为 NULL

一个父进程可能有多个子进程,而wait函数等待的是任意子进程

因此,推荐使用waitpid函数:

 pid_ t waitpid(pid_t pid, int *status, int options);

返回值:

当正常返回的时候 waitpid 返回收集到的⼦进程的进程 ID ;

如果设置了选项 WNOHANG, ⽽调⽤中 waitpid 发现没有已退出的⼦进程可收集 , 则返回 0 ;

如果调⽤中出错 , 则返回-1, 这时 errno 会被设置成相应的值以指⽰错误所在;

参数:

pid :

Pid=-1, 等待任⼀个⼦进程。与 wait 等效。

Pid>0. 等待其进程 ID 与 pid 相等的⼦进程。

status: 输出型参数,为了便于调用,可以使用以下两个宏:

WIFEXITED(status): 若为正常终⽌⼦进程返回的状态,则为真。(查看进程是否是正常退出) WEXITSTATUS(status): 若 WIFEXITED ⾮零,提取⼦进程退出码。(查看进程的退出码)

options:

默认为 0 ,表⽰阻塞等待

WNOHANG: 非阻塞等待,若 pid 指定的⼦进程没有结束,则 waitpid() 函数返回 0 ,不予等待。若正常结束,则返回该⼦进程的 ID 。

status

status用于记录子进程的退出信号和退出码:

前7位为退出信号,第8位为core dump标志(不关心),9~16位为退出码

若退出信号非0,表明进程异常

若退出信号为0,表明进程正常运行

若退出码非0,表明运行结果错误

若退出码非0,表明运行结果正常

阻塞等待与非阻塞轮询等待对比

阻塞等待:

int main(){pid_t pid;pid = fork();if(pid < 0){printf("%s fork error\n",__FUNCTION__);return 1;} else if( pid == 0 ){ //childprintf("child is run, pid is : %d\n",getpid());sleep(5);exit(257);} else{int status = 0;pd_t ret = waitpid(-1, &status, 0);//阻塞式等待,等待5S printf("this is test for wait\n");if( WIFEXITED(status) && ret == pid ){printf("wait child 5s success, child return code is:%d.\n",WEXITSTATUS(status));}else{printf("wait child failed, return.\n");return 1;}}return 0;}

父进程阻塞等待成功

虽然返回的是257,但由于退出码只取8位,所以返回1:

非阻塞轮询等待:

void handler() {printf("临时任务\n");sleep(1);}int main() {pid_t pid;pid = fork();if (pid < 0) {printf("%s fork error\n", __FUNCTION__);return 1;} else if (pid == 0) {  // childprintf("child is run, pid is : %d\n", getpid());sleep(5);exit(1);} else {int status = 0;pid_t ret = 0;do {ret = waitpid(-1, &status, WNOHANG);  //⾮阻塞式等待if (ret == 0) {printf("child is running\n");}handler();} while (ret == 0);if (WIFEXITED(status) && ret == pid) {printf("wait child 5s success, child return code is :%d.\n",WEXITSTATUS(status));} else {printf("wait child failed, return.\n");return 1;}}return 0;}

可以看到父进程一边执行自己的“临时任务”,一边询问子进程是否结束,直到子进程结束,等待结束:

进程替换

我们之前虽然用fork创建了子进程,但是子进程和父进程执行的还是同样的代码,很多时候我们创建子进程就是为了去专门执行某一任务,这就需要用到进程替换,进程替换是通过特定的接⼝,把磁盘上另外的⼀个程序的代码和数据加载到调⽤原先进程的地址空间中。

替换原理

⽤fork创建⼦进程后执⾏的是和⽗进程相同的程序(但有可能执⾏不同的代码分⽀),⼦进程往往要调⽤⼀种exec函数以执⾏另⼀个程序。当进程调⽤⼀种exec函数时,该进程的⽤⼾空间代码和数据完全被新程序替换,从新程序的启动例程开始执⾏。调⽤exec并不创建新进程,所以调⽤exec前后该进程的id并未改变。

替换函数

#include <unistd.h>
int execl(const char *path, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
int execle(const char *path, const char *arg, ...,char *const envp[]);
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
int execve(const char *path, char *const argv[], char *const envp[]);

这些函数如果调⽤成功则加载新的程序从启动代码开始执⾏,不再返回;如果调⽤出错则返回-1 

这里把子进程替换为一个能够读入并执行命令的程序:

#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h> 
int main(int argc, char* argv[])
{pid_t id=fork();if(id==0){     char**  myargv=&argv[1];                                                                                                                                                    execvp(myargv[0],myargv);}waitpid(id,NULL,0);return 0;
}

可以看到子进程可以收集并执行命令

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

相关文章:

  • .net域名 可以做公司网站吗申请自媒体平台注册
  • 重庆网站平台建设河南专业网络推广公司
  • 佛山智能建站百度指数网页版
  • 新人跑业务怎么找客户青岛自动seo
  • 机械免费网站制作百度推广怎么操作
  • 网站布局模板外链seo服务
  • 手机网站弹出层插件有哪些营销策略都有哪些
  • 做网站常见程序火星时代教育培训机构学费多少
  • 深圳建网站找哪家win7优化软件
  • cms网站建设的方法房地产营销策略有哪些
  • 1688做网站需要多少钱深圳整站seo
  • 用网站源码做网站高端定制网站建设公司
  • 嵌入式培训机构排名信阳seo公司
  • 有什么做任务的网站吗手机建站
  • 高端网站设计报价表互联网推广软件
  • wordpress模板无法复制文件路径西安网站seo外包
  • 福州网站设计公司seo优化网络推广
  • 网站分几种类型公众号微博seo
  • 武邑网站建设百度广告搜索推广
  • 长沙微信小程序公司seo优化网站快速排名
  • 网站建设方案书范本重庆森林讲的什么内容
  • 医疗网站建设需要什么资质在线超级外链工具
  • h5制作模板官网杭州网站推广优化
  • 网站建设评审简单的网站制作
  • 推荐西安优秀的高端网站建设公司招聘网络营销推广人员
  • 麦味旅行的网站建设需求分析企业营销策划是做什么的
  • 做网站的总是有活动怎么回事推广网站怎么制作
  • 软件开发模型螺旋模型文章优化软件
  • 房地产公司网站下载雅虎搜索引擎首页
  • 电商类公司网站应该怎么搭建百度seo排名优化公司