栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

002.进程api

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

002.进程api

1.fork()系统调用

系统调用 fork()用于创建新进程.

#include 
#include 
#include 

int main(int argc, char *argv[])
{
    printf("hello world (pid:%d)n", (int) getpid());
    int rc = fork();

    if (rc < 0) { // fork failed; exit
        fprintf(stderr, "fork failedn");
        exit(1);
    } else if (rc == 0) { // child (new process)
        printf("hello, I am child (pid:%d)n", (int) getpid());
    } else { // parent goes down this path (main)
        printf("hello, I am parent of %d (pid:%d)n",rc, (int) getpid());
    }
    return 0;
 }

  • 开始运行时,进程输出一条 hello world 信息,以及自己的进程描述符(process identifier,PID)。该进程的 PID 是 3580078,输出是不确定的(deterministic)(每个人电脑不一样,每次运行的结果也不同),之后进程调用了 fork()系统调用,这是操作系统提供的创建新进程的方法。
  • 新创建的进程称为子进程(child),原来的进程称为父进程(parent)。子进程不会从 main()函数开始执行(故而 hello world 信息只输出了一次),而是直接从 fork()系统调用返回,就好像是它自己调用了 fork()。
  • 子进程并不是完全拷贝了父进程。它拥有自己的私有内存、寄存器、程序计数器等,但是它从 fork()返回的值是不同的。
  • 父进程获得的返回值是新创建子进程的 PID,而子进程获得的返回值是 0。
2.wait()系统调用

有时候父进程需要等待子进程执行完毕,此时需要 wait()系统调用

#include 
#include 
#include 
#include 

int main(int argc, char *argv[])
{
    printf("hello world (pid:%d)n", (int) getpid());
    int rc = fork();
    if (rc < 0) { // fork failed; exit
        fprintf(stderr, "fork failedn");
        exit(1);
    } else if (rc == 0) { // child (new process)
        printf("hello, I am child (pid:%d)n", (int) getpid());
    } else { // parent goes down this path (main)
        int wc = wait(NULL);
        printf("hello, I am parent of %d (wc:%d) (pid:%d)n",rc, wc, (int) getpid());
    }
    return 0;
 }

  • 父进程调用 wait(),延迟自己的执行,直到子进程执行完毕。当子进程结束时,wait()才返回父进程。
  • 该系统调用会等待子进程运行结束后才返回。因此,即使父进程先运行,它也会等待子进程运行完毕,然后 wait()返回,接着父进程输出自己的信息。
3.exec()系统调用

该系统调用可以使子进程执行与父进程不同的程序
vim m.c

#include 
#include 
#include 
#include 
#include 

int main(int argc, char *argv[]) {
    printf("hello world (pid:%d)n", (int) getpid());

    int rc = fork();
    if (rc < 0) { // fork failed; exit
        fprintf(stderr, "fork failedn");
        exit(1);
    } else if (rc == 0) { // child (new process)

        printf("hello, I am child (pid:%d)n", (int) getpid());
        char *myargs[3];
        myargs[0] = strdup("wc"); // program: "wc" (word count)
        myargs[1] = strdup("m.c"); // argument: file to count
        myargs[2] = NULL; // marks end of array
        execvp(myargs[0], myargs); // runs word count
        printf("this shouldn't print out");
    } else { // parent goes down this path (main)
        int wc = wait(NULL);
        printf("hello, I am parent of %d (wc:%d) (pid:%d)n",rc, wc, (int) getpid());
    }
    return 0;
}

  • 子进程调用 execvp()来运行字符计数程序 wc。对m.c运行 wc,该文件有多少行、多少单词,以及多少字节。
  • exec()会从可执行程序中加载代码和静态数据,并用它覆写自己的代码段(以及静态数据),堆、栈及其他内存空间也会被重新初始化。然后操作系统就执行该程序,将参数通过 argv 传递给该进程。因此,它并没有创建新进程,而是直接将当前运行的程序替换为不同的运行程序(wc)。子进程执行 exec()之后,几乎就像m.c 从未运行过一样。对 exec()的成功调用永远不会返回。
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/875190.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号