进程管理(一)

简介: 版权声明:您好,转载请留下本人博客的地址,谢谢 https://blog.csdn.net/hongbochen1223/article/details/46510913 (一):进程的概念​线程,是在进程中活动的对象。
版权声明:您好,转载请留下本人博客的地址,谢谢 https://blog.csdn.net/hongbochen1223/article/details/46510913

(一):进程的概念

​线程,是在进程中活动的对象。每个线程都拥有一个独立的程序计数器,进程栈和一组进程寄存器。内核调度的是线程而不是进程。在Linux中,进程和线程的区别比较微妙,一会我们通过源码来查看其两个的区别。

进程提供两种虚拟机制,虚拟处理器和虚拟内存。其中在线程之间可以共享虚拟内存,但是每个线程都拥有各自的虚拟处理器。

在linux中,创建一个进程的函数是fork(),该系统调用通过复制一个现有的进程来创建一个全新的进程。调用fork()的进程称为父进程,被创建的进程成为子进程。fork()系统调用从内核中返回两次:一次回到父进程,一次回到子进程。通常,创建新的进程都是为了立即执行新的,不同的程序,所以,在创建新的子进程之后,会接着调用exec()函数,来创建新的地址空间,并且把新的程序载入到子进程中。最终,程序通过exit()系统调用退出执行。这个函数会终结进程并将其占有的资源释放掉。父进程可以通过wait4()系统调用查询子进程是否终结,这其实使得进程拥有了等待特定进程执行完毕的能力。进程退出执行后被设置为僵死状态,直到它的父进程调用wait()或waitpid()为止。

​exec函数族:
​定义在

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 *constargv[]);
int execvp(const char *file, char *constargv[]);
int execve(const char *path, char *constargv[], char *const envp[]);

​其中, ​execv()函数中的参数,第一个参数const char *path为所运行成程序的地址,char *constargv[]为传递给所运行程序的参数。

下面我们看一下一个进程的创建,执行程序和终止。

#include <unistd.h>
#include <stdio.h>
int main()
{
    int pid,status;
    pid = fork();
    if(pid < 0){
        printf("error!!
");
    }else if(pid == 0){
        printf("I am the child forked!!,My pid is %d
",getpid());
        execv("/bin/ls","-l");
    }else{
        printf("I am the parent!! My pid is %d
",getpid());
        waitpid(pid,&status,0);
        printf("Child %d exit %d
",pid,status);
    }
    return 0;
}

这个仅仅就是一个简单的例子,通过这个例子,就可以扩展出更多的子进程,其实,在内核程序开始的时候,程序的创建都是这样进行的。
下面是程序的运行结果:

这里写图片描述

(二):进程描述符以及任务结构

内核把进程的列表存放在任务队列中,该任务队列是一个双向循环链表。链表中的每一项都是类型为task_struct结构体,称之为进程描述符。该结构定义在

struct task_struct {
    volatile long state;    /* -1 unrunnable, 0 runnable, >0 stopped */
    struct thread_info *thread_info;
    atomic_t usage;
    unsigned long flags;    /* per process flags, defined below */
    unsigned long ptrace;
    int lock_depth;     /* BKL lock depth */
#ifdef CONFIG_SMP
#ifdef __ARCH_WANT_UNLOCKED_CTXSW
    int oncpu;
#endif
#endif
    int load_weight;    /* for niceness load balancing purposes */
    int prio, static_prio, normal_prio;
    struct list_head run_list;
    struct prio_array *array;
    unsigned short ioprio;
    unsigned int btrace_seq;
    unsigned long sleep_avg;
    unsigned long long timestamp, last_ran;
    unsigned long long sched_time; /* sched_clock time spent running */
    enum sleep_type sleep_type;
    unsigned long policy;
    cpumask_t cpus_allowed;
    unsigned int time_slice, first_time_slice;
#if defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT)
    struct sched_info sched_info;
#endif
    struct list_head tasks;
    /*
     * ptrace_list/ptrace_children forms the list of my children
     * that were stolen by a ptracer.
     */
    struct list_head ptrace_children;
    struct list_head ptrace_list;
    struct mm_struct *mm, *active_mm;
/* task state */
    struct linux_binfmt *binfmt;
    long exit_state;
    int exit_code, exit_signal;
    int pdeath_signal;  /*  The signal sent when the parent dies  */
    /* ??? */
    unsigned long personality;
    unsigned did_exec:1;
    pid_t pid;
    pid_t tgid;
    /* 
     * pointers to (original) parent process, youngest child, younger sibling,
     * older sibling, respectively.  (p->father can be replaced with 
     * p->parent->pid)
     */
    struct task_struct *real_parent; /* real parent process (when being debugged) */
    struct task_struct *parent; /* parent process */
    /*
     * children/sibling forms the list of my children plus the
     * tasks I'm ptracing.
     */
    struct list_head children;  /* list of my children */
    struct list_head sibling;   /* linkage in my parent's children list */
    struct task_struct *group_leader;   /* threadgroup leader */
    /* PID/PID hash table linkage. */
    struct pid_link pids[PIDTYPE_MAX];
    struct list_head thread_group;
    struct completion *vfork_done;      /* for vfork() */
    int __user *set_child_tid;      /* CLONE_CHILD_SETTID */
    int __user *clear_child_tid;        /* CLONE_CHILD_CLEARTID */
    unsigned long rt_priority;
    cputime_t utime, stime;
    unsigned long nvcsw, nivcsw; /* context switch counts */
    struct timespec start_time;
/* mm fault and swap info: this can arguably be seen as either mm-specific or thread-specific */
    unsigned long min_flt, maj_flt;
    cputime_t it_prof_expires, it_virt_expires;
    unsigned long long it_sched_expires;
    struct list_head cpu_timers[3];
/* process credentials */
    uid_t uid,euid,suid,fsuid;
    gid_t gid,egid,sgid,fsgid;
    struct group_info *group_info;
    kernel_cap_t   cap_effective, cap_inheritable, cap_permitted;
    unsigned keep_capabilities:1;
    struct user_struct *user;
#ifdef CONFIG_KEYS
    struct key *request_key_auth;   /* assumed request_key authority */
    struct key *thread_keyring; /* keyring private to this thread */
    unsigned char jit_keyring;  /* default keyring to attach requested keys to */
#endif
    int oomkilladj; /* OOM kill score adjustment (bit shift). */
    char comm[TASK_COMM_LEN]; /* executable name excluding path
                     - access with [gs]et_task_comm (which lock
                       it with task_lock())
                     - initialized normally by flush_old_exec */
/* file system info */
    int link_count, total_link_count;
/* ipc stuff */
    struct sysv_sem sysvsem;
/* CPU-specific state of this task */
    struct thread_struct thread;
/* filesystem information */
    struct fs_struct *fs;
/* open file information */
    struct files_struct *files;
/* namespace */
    struct namespace *namespace;
/* signal handlers */
    struct signal_struct *signal;
    struct sighand_struct *sighand;
    sigset_t blocked, real_blocked;
    sigset_t saved_sigmask;     /* To be restored with TIF_RESTORE_SIGMASK */
    struct sigpending pending;
    unsigned long sas_ss_sp;
    size_t sas_ss_size;
    int (*notifier)(void *priv);
    void *notifier_data;
    sigset_t *notifier_mask;

    void *security;
    struct audit_context *audit_context;
    seccomp_t seccomp;
/* Thread group tracking */
    u32 parent_exec_id;
    u32 self_exec_id;
/* Protection of (de-)allocation: mm, files, fs, tty, keyrings */
    spinlock_t alloc_lock;
    /* Protection of the PI data structures: */
    spinlock_t pi_lock;
#ifdef CONFIG_RT_MUTEXES
    /* PI waiters blocked on a rt_mutex held by this task */
    struct plist_head pi_waiters;
    /* Deadlock detection and priority inheritance handling */
    struct rt_mutex_waiter *pi_blocked_on;
#endif
#ifdef CONFIG_DEBUG_MUTEXES
    /* mutex deadlock detection */
    struct mutex_waiter *blocked_on;
#endif
#ifdef CONFIG_TRACE_IRQFLAGS
    unsigned int irq_events;
    int hardirqs_enabled;
    unsigned long hardirq_enable_ip;
    unsigned int hardirq_enable_event;
    unsigned long hardirq_disable_ip;
    unsigned int hardirq_disable_event;
    int softirqs_enabled;
    unsigned long softirq_disable_ip;
    unsigned int softirq_disable_event;
    unsigned long softirq_enable_ip;
    unsigned int softirq_enable_event;
    int hardirq_context;
    int softirq_context;
#endif
#ifdef CONFIG_LOCKDEP
# define MAX_LOCK_DEPTH 30UL
    u64 curr_chain_key;
    int lockdep_depth;
    struct held_lock held_locks[MAX_LOCK_DEPTH];
    unsigned int lockdep_recursion;
#endif
/* journalling filesystem info */
    void *journal_info;
/* VM state */
    struct reclaim_state *reclaim_state;
    struct backing_dev_info *backing_dev_info;
    struct io_context *io_context;
    unsigned long ptrace_message;
    siginfo_t *last_siginfo; /* For ptrace use.  */
/*
 * current io wait handle: wait queue entry to use for io waits
 * If this thread is processing aio, this points at the waitqueue
 * inside the currently handled kiocb. It may be NULL (i.e. default
 * to a stack based synchronous wait) if its doing sync IO.
 */
    wait_queue_t *io_wait;
/* i/o counters(bytes read/written, #syscalls */
    u64 rchar, wchar, syscr, syscw;
#if defined(CONFIG_BSD_PROCESS_ACCT)
    u64 acct_rss_mem1;  /* accumulated rss usage */
    u64 acct_vm_mem1;   /* accumulated virtual memory usage */
    clock_t acct_stimexpd;  /* clock_t-converted stime since last update */
#endif
#ifdef CONFIG_NUMA
    struct mempolicy *mempolicy;
    short il_next;
#endif
#ifdef CONFIG_CPUSETS
    struct cpuset *cpuset;
    nodemask_t mems_allowed;
    int cpuset_mems_generation;
    int cpuset_mem_spread_rotor;
#endif
    struct robust_list_head __user *robust_list;
#ifdef CONFIG_COMPAT
    struct compat_robust_list_head __user *compat_robust_list;
#endif
    struct list_head pi_state_list;
    struct futex_pi_state *pi_state_cache;
    atomic_t fs_excl;   /* holding fs exclusive resources */
    struct rcu_head rcu;
    /*
     * cache last used pipe for splice
     */
    struct pipe_inode_info *splice_pipe;
#ifdef  CONFIG_TASK_DELAY_ACCT
    struct task_delay_info *delays;
#endif
};
目录
相关文章
|
5天前
|
消息中间件 算法 Linux
深入理解操作系统之进程管理
【10月更文挑战第30天】在数字时代的浪潮中,操作系统作为计算机系统的核心,扮演着至关重要的角色。本文将深入浅出地探讨操作系统中的进程管理机制,从进程的概念入手,逐步解析进程的创建、调度、同步与通信等关键过程,并通过实际代码示例,揭示这些理论在Linux系统中的应用。文章旨在为读者提供一扇窥探操作系统深层工作机制的窗口,同时激发对计算科学深层次理解的兴趣和思考。
|
1月前
|
消息中间件 Linux 调度
深入理解操作系统的进程管理
【9月更文挑战第34天】本文将深入浅出地介绍操作系统中的进程管理,从进程的概念开始,逐步展开到进程调度、进程同步与通信等核心内容。我们将通过简单的代码示例,帮助读者更好地理解进程管理的原理和实践。无论你是初学者还是有一定基础的开发者,这篇文章都将为你提供有价值的参考。
38 12
|
3月前
|
算法 调度 开发者
深入理解操作系统:进程管理与调度算法
在数字时代的心脏,操作系统扮演着至关重要的角色。它不仅是计算机硬件与软件之间的桥梁,更是确保多任务高效运行的守护者。本文将带你一探操作系统中进程管理的奥秘,并通过实际代码示例深入解析进程调度算法。无论你是编程新手还是资深开发者,了解这些基础概念都将有助于你更好地理解计算机工作原理,并提升你对系统性能调优的认识。准备好,让我们一起揭开操作系统的神秘面纱!【8月更文挑战第31天】
|
调度
操作系统概论学习(进程管理)
操作系统概论学习(进程管理)
57 0
|
6月前
|
存储 算法 安全
|
消息中间件 算法 安全
进程管理
一、进程管理 进程管理是操作系统的重要功能之一,它负责管理和控制计算机系统中的各个进程。进程是指正在执行的程序的实例,它包括程序代码、数据、执行状态等信息。 进程管理主要包括以下几个方面: 1. 进程创建:操作系统负责创建新的进程。当用户或应用程序发起创建进程的请求时,操作系统会为新进程分配资源,并初始化进程的执行环境。 2. 进程调度:操作系统负责调度和分配CPU时间片给各个进程。它根据调度算法和优先级策略,决定哪个进程可以获得CPU的执行权,以实现多任务并发执行。 3. 进程同步:操作系统提供了各种机制来实现进程之间的同步和协作。例如,信号量、互斥锁、条件变量等,可以用来解决进程间的互斥访
106 0
|
存储 算法 安全
操作系统之进程管理
进程的定义、特征、组成、组织 进程的定义 PCB 是进程控制块(Process Control Block)的缩写,它是操作系统中用于管理进程的重要数据结构。 进程的组成 进程的组织 链接方式: 索引方式: 进程的特征 本章内容小结: 进程的状态与转换 进程的状态 三种基本状态: 另外两种状态: 创建态: 结束态: 进程状态的转换 本章小结: 进程控制 什么是进程控制 进程控制过程 如何实现进程控制 进程控制相关的原语 本章回顾: 进程通信 什么是系统资源? 系统资源包括: CPU: 中央处理器,
65 0
|
资源调度 调度 索引
操作系统进程管理描述
操作系统进程管理描述
|
存储 算法 调度
操作系统(2)进程管理(上)进程与线程
2.1.概述 2.2.CPU的管理 CPU本质上就是一个去内存中根据地址取指令,然后执行指令的硬件。CPU的完整取址执行流程如下: CPU要执行的指令的地址存在寄存器中,指令存放在内存中。 例如PC寄存器中存放50,CPU读到存放的50,发出一条取址指令,经由地址总线去取出地址为50的内存单元中的指令。最后CPU解释执行该指令,CPU工作的过程就是不断的取址执行。
141 0
|
安全 算法 测试技术
进程管理和死锁避免
进程管理和死锁避免
108 0
进程管理和死锁避免