0
点赞
收藏
分享

微信扫一扫

进程体系与进程管理

一、进程控制块PCB

task_struct结构体:

  • 进程id:系统中每个进程有唯一的id,在c语言中用pid_t类型表示,就是一个非负整数。

  • 进程的状态:有运行,挂起,停止,僵尸等状态。

  • 进程切换时需要保存和恢复的一些CPU寄存器。

  • 描述虚拟地址空间的信息。

  • 描述控制终端的信息。

  • 当前工作目录。

  • umask掩码。

  • 文件描述符表,包含很多指向file结构体的指针。

  • 和信号相关的信息。

  • 用户id和组id。

  • 控制终端、session和进程组。

  • 进程可以使用的资源上限。

二、进程控制fork

1.fork作用:

根据一个现有的进程复制出一个新进程,原来的进程称为父进程,新进程称为子进程。

系统中运行着很多进程,这些进程都是从最初只有一个进程开始一个一个复制出来的。

2.在shell下输入命令运行一个程序,因为shell进程在读取用户输入的命令之后会调用fork夫指出一个新的shell进程。

fork调用失败返回-1。

fork在子进程中返回0,子进程可以调用getpid函数得到自己的进程id,也可调用getpid函数得到父进程id。

在父进程中用getpid得到自己的进程id,要想得到子进程id,只有将fork返回值记录下来!

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int main(void) {
    char *msg;
    int n;
    pid_t pid = fork();
    if (pid < 0) {
        perror("fork");
        exit(1);
    }
    if (pid == 0) {
        n=6;
        while (n > 0) {
            printf("child self=%d, parent=%d\n", getpid(), getppid());
            sleep(1);
            n--;
        }
    } else {
        n = 3;
        while (n > 0) {
            printf("father self=%d, parent=%d\n", getpid(), getppid());
            sleep(1);
            n--;
        }
    }
    return 0;
}

3.创建10个子进程,并打印他们的pid和ppid?

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int main(void) {
    char *msg;
    int n;
    for (int i = 0; i < 10; i++) {
        pid_t pid = fork();
        if (pid < 0) {
            perror("fork");
            exit(1);
        }

        if (!pid) {
            sleep(1);
            printf("child[%d], self=%d, parent=%d\n", i, getpid(), getppid());
            break;
        }
    }
    return 0;
}

4.gdb如何调试多进程?

三、exec函数族

1.当进程调用一种exec函数时,该进程的用户空间代码和数据完全被新程序替换,从新程序的启动例程开始执行。

如果调用成功则加载新的程序从启动代码开始执行,不在返回,如果出错返回-1。

exec函数只有出错的返回值而没有成功的返回值。

exec系统调用执行新程序时会把命令行参数和环境变量表传递给main函数。

和命令行参数argv类似,环境变量表也是一个字符串数组。

name=value

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int main(void) {
    printf("path value = [%s]\n", getenv("PATH"));
    setenv("PATH", "hello", 1);
    printf("path value = [%s]\n", getenv("PATH"));

    // extern char **environ;
    // for (int i = 0; environ[i]; i++) {
    //     printf("%s\n", environ[i]);
    // }
    return 0;
}

①不带字母p(path)的exec函数第一个参数必须是程序的相对路径或绝对路径,如:“/bin/ls”或“./a.out”

②对于带字母p的函数:如果参数中包含/,将其视为路径名。否则视为不带路径的程序名,在PATH环境变量的目录列表中搜索这个程序。

③对于以e(environment)结尾的exec函数,可以把一份新的环境表量表与其他exec仍使用当前的环境变量表执行新程序。

2.实现exec族函数调用命令,实现流的重定向

 

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int main(void) {
    execlp("ls", "ls", "-a", "-l", NULL);
    perror("exec");
    exit(1);
    return 0;
}
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int main(void) {
    char *arr[] = {"hello", "-a", "-l", NULL};
    execvp("ls", arr);
    perror("exec");
    exit(1);
}
举报

相关推荐

0 条评论