您好,登录后才能下订单哦!
# Linux进程怎么创建和启动
## 1. 进程基础概念
### 1.1 什么是进程
进程(Process)是Linux系统中程序执行的基本单位,它是操作系统资源分配和调度的独立实体。每个进程都有自己独立的地址空间、堆栈、文件描述符等系统资源。
进程与程序的区别:
- 程序是静态的存储在磁盘上的可执行文件
- 进程是程序在内存中的动态执行实例
### 1.2 进程的生命周期
Linux进程通常经历以下状态变化:
1. 创建(Created)
2. 就绪(Ready)
3. 运行(Running)
4. 阻塞(Blocked)
5. 终止(Terminated)
## 2. 进程创建机制
### 2.1 fork()系统调用
`fork()`是Linux创建新进程的基本方式:
```c
#include <unistd.h>
pid_t fork(void);
工作原理: 1. 复制父进程的地址空间、堆栈、文件描述符等 2. 创建新的进程控制块(PCB) 3. 返回两次: - 父进程中返回子进程PID - 子进程中返回0
示例代码:
#include <stdio.h>
#include <unistd.h>
int main() {
    pid_t pid = fork();
    
    if (pid < 0) {
        perror("fork failed");
        return 1;
    } else if (pid == 0) {
        printf("This is child process (PID: %d)\n", getpid());
    } else {
        printf("This is parent process (PID: %d), child PID: %d\n", 
               getpid(), pid);
    }
    return 0;
}
现代Linux系统采用写时复制优化fork()性能: - 父子进程最初共享相同的物理内存页 - 只有当任一进程尝试修改内存页时,才会复制该页 - 显著减少fork()的开销
exec函数族用于将当前进程映像替换为新的程序:
#include <unistd.h>
int execl(const char *path, const char *arg, ...);
int execv(const char *path, char *const argv[]);
int execle(const char *path, const char *arg, ..., char *const envp[]);
int execve(const char *path, char *const argv[], char *const envp[]);
int execlp(const char *file, const char *arg, ...);
int execvp(const char *file, char *const argv[]);
典型使用模式:
pid_t pid = fork();
if (pid == 0) {
    // 子进程
    execl("/bin/ls", "ls", "-l", NULL);
    perror("exec failed");
    exit(1);
}
Linux标准进程创建流程: 1. 父进程调用fork()创建子进程 2. 子进程调用exec()加载新程序 3. 父进程通过wait()等待子进程结束
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
int main() {
    pid_t pid = fork();
    
    if (pid == 0) {
        // 子进程
        execlp("ls", "ls", "-l", NULL);
        perror("exec failed");
        return 1;
    } else if (pid > 0) {
        // 父进程
        int status;
        waitpid(pid, &status, 0);
        printf("Child process exited with status %d\n", WEXITSTATUS(status));
    } else {
        perror("fork failed");
        return 1;
    }
    return 0;
}
简化版的进程创建和启动:
#include <stdlib.h>
int system(const char *command);
示例:
#include <stdlib.h>
int main() {
    int ret = system("ls -l /");
    printf("Command exited with status %d\n", ret);
    return 0;
}
注意:system()会创建shell进程来执行命令,存在安全风险。
更高效的进程创建方式:
#include <spawn.h>
int posix_spawn(pid_t *pid, const char *path,
                const posix_spawn_file_actions_t *file_actions,
                const posix_spawnattr_t *attrp,
                char *const argv[], char *const envp[]);
优点: - 合并了fork和exec操作 - 允许更精细控制文件描述符和属性
提供更灵活的进程创建:
#define _GNU_SOURCE
#include <sched.h>
int clone(int (*fn)(void *), void *child_stack,
          int flags, void *arg, ...);
特点: - 可以控制共享哪些资源 - 用于实现线程(轻量级进程)
重要环境变量: - PATH:命令搜索路径 - LD_LIBRARY_PATH:动态库搜索路径 - HOME:用户主目录
启动后台进程:
command &
创建守护进程: 1. fork()创建子进程 2. 子进程调用setsid()创建新会话 3. 改变工作目录到/ 4. 重定向标准I/O 5. 处理信号
影响因素: - 进程地址空间大小 - 页表复制开销 - 写时复制触发频率
优化策略: - 减少不必要的fork() - 使用vfork()(已过时,不推荐) - 考虑posix_spawn()
影响因素: - 程序文件大小 - 动态链接库数量 - 环境变量数量
优化策略: - 静态链接减少动态库加载 - 精简环境变量 - 使用execve()直接指定环境
设置资源限制:
#include <sys/resource.h>
setrlimit(RLIMIT_CPU, &limit);
常见限制类型: - CPU时间 - 内存使用 - 文件大小 - 进程数
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>
#define MAX_ARGS 20
void parse_command(char *cmd, char **argv) {
    char *token = strtok(cmd, " ");
    int i = 0;
    while (token != NULL && i < MAX_ARGS-1) {
        argv[i++] = token;
        token = strtok(NULL, " ");
    }
    argv[i] = NULL;
}
int main() {
    char cmd[256];
    char *argv[MAX_ARGS];
    
    while (1) {
        printf("mysh> ");
        if (fgets(cmd, sizeof(cmd), stdin) == NULL) {
            break;
        }
        
        cmd[strcspn(cmd, "\n")] = '\0'; // 移除换行符
        if (strlen(cmd) == 0) continue;
        
        parse_command(cmd, argv);
        
        if (strcmp(argv[0], "exit") == 0) {
            break;
        }
        
        pid_t pid = fork();
        if (pid == 0) {
            execvp(argv[0], argv);
            perror("exec failed");
            exit(1);
        } else if (pid > 0) {
            wait(NULL);
        } else {
            perror("fork failed");
        }
    }
    return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#define POOL_SIZE 5
void worker(int id) {
    printf("Worker %d (PID: %d) started\n", id, getpid());
    sleep(3);
    printf("Worker %d (PID: %d) finished\n", id, getpid());
    exit(0);
}
int main() {
    int i;
    pid_t pids[POOL_SIZE];
    
    // 创建工作进程
    for (i = 0; i < POOL_SIZE; i++) {
        pids[i] = fork();
        if (pids[i] == 0) {
            worker(i);
        } else if (pids[i] < 0) {
            perror("fork failed");
            exit(1);
        }
    }
    
    // 等待所有工作进程结束
    for (i = 0; i < POOL_SIZE; i++) {
        waitpid(pids[i], NULL, 0);
    }
    
    printf("All workers completed\n");
    return 0;
}
使用strace跟踪:
strace -f -e trace=process command
pstree -p
使用time测量:
time command
使用perf分析:
perf stat command
Linux进程创建和启动涉及多个关键系统调用和复杂机制:
掌握这些知识对于Linux系统编程、性能优化和安全加固都至关重要。 “`
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。