linux进程 线程详解

进程

在 Linux 操作系统中,进程是执行中的程序的实例。理解进程及其管理是系统编程、性能调优和系统管理的基础。以下是对 Linux 进程的详细介绍,包括进程的基本概念、生命周期、管理以及常用的命令和工具。

基本概念
进程(Process):

进程是程序在执行中的实例。每个进程都有一个唯一的进程标识符(PID)以及一组资源(如内存、文件描述符等)。
线程(Thread):

线程是进程内的一个执行单元。一个进程可以包含多个线程,共享进程的资源和内存。
任务(Task):

在 Linux 内核中,进程被称为任务(task)。每个任务有一个任务结构(task_struct)来管理其状态、资源和其他信息。
进程生命周期
进程的生命周期包括以下几个主要状态:

创建(Creation):

使用系统调用如 fork() 创建新进程。父进程创建子进程,子进程是父进程的副本。
就绪(Ready):

就绪状态的进程已准备好执行,但尚未分配 CPU 时间。
运行(Running):

进程正在 CPU 上执行。
等待(Waiting):

进程等待某些事件发生(如 I/O 操作完成),不在执行中。
终止(Terminated):

进程完成其执行或被强制终止,释放其占用的资源。
进程管理
进程创建:

fork():创建新进程,子进程是父进程的副本。
exec():替换当前进程的映像,用于执行新程序。
clone():类似于 fork(),但提供更细粒度的控制,支持创建线程。
进程控制:

wait() 和 waitpid():父进程可以等待子进程结束并获取其退出状态。
kill():向进程发送信号,如终止信号(SIGTERM)或中断信号(SIGINT)。
exit():进程退出,并返回一个状态码给其父进程。
进程调度:

Linux 内核使用调度算法(如完全公平调度器 CFS)来分配 CPU 时间给各个进程。
进程调度涉及到上下文切换,内核保存和恢复进程的状态。
进程相关命令
ps:列出当前系统上的进程。

ps aux       # 列出所有进程
ps -ef        # 另一种格式列出所有进程

top:实时显示系统进程的资源使用情况。

top

htop:类似于 top,但提供更友好的用户界面(需要安装)。

htop

kill:向进程发送信号(如终止进程)。

kill PID      # 发送默认的 SIGTERM 信号
kill -9 PID   # 发送 SIGKILL 信号强制终止进程

pkill 和 pgrep:根据进程名称发送信号或查找进程 ID

pkill process_name   # 发送信号给所有名为 process_name 的进程
pgrep process_name   # 查找所有名为 process_name 的进程的 PID

nice 和 renice:调整进程的优先级。

nice -n 10 command   # 以调整后的优先级运行命令
renice 10 -p PID     # 修改运行中进程的优先级

进程的优先级和调度
优先级(Priority):

每个进程都有一个优先级,决定了其获得 CPU 时间的优先顺序。优先级可以通过 nice 和 renice 命令调整。
调度策略(Scheduling Policy):

Linux 支持多种调度策略,如:
SCHED_FIFO:实时调度策略,优先级最高的进程首先获得 CPU 时间。
SCHED_RR:轮转实时调度策略,具有相同优先级的进程轮流获得 CPU 时间。
SCHED_OTHER:默认的时间共享调度策略,基于 CFS(完全公平调度器)。
进程间通信(IPC)
进程间通信(IPC)允许不同进程交换数据和消息。常用的 IPC 机制包括:

管道(Pipes):

单向数据流,使用 pipe() 系统调用创建。
命名管道(FIFO):

有名的管道,可以在不同的进程之间进行双向通信。
消息队列(Message Queues):

允许进程将消息发送到队列,并从队列中读取消息。
共享内存(Shared Memory):

允许多个进程访问同一块内存区域。
信号量(Semaphores):

用于同步进程对共享资源的访问。
信号(Signals):

通过发送和处理信号进行进程间通信,如 SIGINT、SIGTERM。
总结
在 Linux 系统中,进程是程序执行的基本单位,管理进程涉及创建、调度、终止等操作。理解进程的生命周期、管理机制和相关命令对系统编程和性能调优非常重要。进程间通信(IPC)机制使得进程能够有效地协作和交换数据。

线程

在 Linux 操作系统中,线程(Thread)是进程(Process)的一个执行单元。线程共享进程的资源,如内存和文件描述符,同时可以独立执行。以下是关于 Linux 线程的详细介绍,包括线程的基本概念、创建、管理、调度以及与进程的关系。

基本概念
线程(Thread):

线程是进程内的一个执行流,多个线程可以共享同一进程的资源,如地址空间、文件描述符和信号处理。
线程与进程的区别:

进程:有独立的地址空间、全局变量、文件描述符等,进程之间隔离。
线程:同一进程内的线程共享进程资源,线程之间的切换开销比进程间切换小。
线程的优势:

资源共享:线程共享进程的内存和文件描述符,提高了资源利用率。
更轻量:线程创建和切换的开销较小,适合高并发任务。
并行处理:多线程可以在多核处理器上并行执行,提高了程序的执行效率。
创建线程
在 Linux 中,线程可以通过多种方式创建和管理,主要方式包括 pthread 库和 clone() 系统调用。

pthread 库:

pthread(POSIX Threads)是 POSIX 标准定义的线程库,提供了创建和管理线程的 API。
常用的 pthread 函数包括:
pthread_create():创建新线程。
pthread_join():等待线程结束。
pthread_exit():终止当前线程。
pthread_mutex_lock() 和 pthread_mutex_unlock():线程间同步。
示例:

#include <pthread.h>
#include <stdio.h>

void* thread_function(void* arg) {
    printf("Hello from the thread!\n");
    return NULL;
}

int main() {
    pthread_t thread;
    pthread_create(&thread, NULL, thread_function, NULL);
    pthread_join(thread, NULL);
    return 0;
}

clone() 系统调用:

clone() 是 Linux 特有的系统调用,提供了更细粒度的线程创建功能。可以指定线程共享的资源。
clone() 可以创建线程,也可以用于实现轻量级进程(如容器)。
示例:

#define _GNU_SOURCE
#include <sched.h>
#include <stdio.h>
#include <stdlib.h>

int child_function(void* arg) {
    printf("Hello from the child thread!\n");
    return 0;
}

int main() {
    char *stack;
    char *stack_top;
    int stack_size = 1024 * 1024; // 1 MB stack
    
    stack = malloc(stack_size);
    if (!stack) {
        perror("malloc");
        exit(EXIT_FAILURE);
    }
    stack_top = stack + stack_size;
    
    int clone_flags = CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_PARENT_SETTID | CLONE_CHILD_CLEARTID | CLONE_SYSVSEM;
    
    int child_pid = clone(child_function, stack_top, clone_flags, NULL);
    if (child_pid == -1) {
        perror("clone");
        exit(EXIT_FAILURE);
    }
    
    // Parent process code
    printf("Hello from the parent process!\n");
    
    // Wait for the child thread to complete
    waitpid(child_pid, NULL, 0);
    
    free(stack);
    return 0;
}

线程管理
线程调度:

线程调度由 Linux 内核负责,内核会根据调度策略和优先级决定哪个线程获得 CPU 时间。
Linux 使用完全公平调度器(CFS)来调度线程。
线程同步:

线程共享进程资源,必须使用同步机制来避免竞争条件和数据不一致。
常用的同步机制包括:
互斥锁(Mutexes):通过 pthread_mutex_lock() 和 pthread_mutex_unlock() 实现。
条件变量(Condition Variables):通过 pthread_cond_wait() 和 pthread_cond_signal() 实现。
读写锁(Read/Write Locks):通过 pthread_rwlock_rdlock() 和 pthread_rwlock_wrlock() 实现。
信号量(Semaphores):通过 sem_wait() 和 sem_post() 实现。
线程状态:

运行(Running):线程正在 CPU 上执行。
就绪(Ready):线程已准备好执行,但等待分配 CPU 时间。
阻塞(Blocked):线程因等待资源或事件而暂时无法执行。
结束(Terminated):线程已完成执行,等待清理资源。
线程与进程的关系
线程与进程:

一个进程可以有多个线程,这些线程共享进程的资源,如地址空间和文件描述符。
线程之间的切换开销比进程间切换小,适合高并发任务。
进程创建和线程创建:

进程可以通过 fork() 系统调用创建,线程则通过 pthread_create() 或 clone() 创建。
常用命令和工具
ps:显示进程信息,包括线程。

ps -eLf      # 显示所有进程和线程

top 和 htop:实时显示系统进程和线程的资源使用情况。

pstree:显示进程和线程的树形结构。

pstree -p    # 显示进程和线程的树状图及其 PID

strace:跟踪系统调用,包括线程相关的调用。

strace -e trace=thread ./my_program

总结
在 Linux 中,线程是进程内的执行单元,它们共享进程的资源并能够并行执行。线程的创建、管理和调度是系统编程的重要部分。通过 pthread 库或 clone() 系统调用可以创建和管理线程。线程同步机制(如互斥锁、条件变量等)用于确保多线程环境中的数据一致性。理解线程的基本概念和管理方式对于高效编程和系统优化至关重要。

  • 19
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值