博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
进程管理(一)
阅读量:5827 次
发布时间:2019-06-18

本文共 8682 字,大约阅读时间需要 28 分钟。

(一):进程的概念

​线程,是在进程中活动的对象。每个线程都拥有一个独立的程序计数器,进程栈和一组进程寄存器。内核调度的是线程而不是进程。在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 
#include
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};

转载于:https://www.cnblogs.com/bobo1223/p/7287572.html

你可能感兴趣的文章
Linux 目录结构及内容详解
查看>>
OCP读书笔记(24) - 题库(ExamD)
查看>>
.net excel利用NPOI导入oracle
查看>>
$_SERVER['SCRIPT_FLENAME']与__FILE__
查看>>
hive基本操作与应用
查看>>
html5纲要,细谈HTML 5新增的元素
查看>>
Android应用集成支付宝接口的简化
查看>>
[分享]Ubuntu12.04安装基础教程(图文)
查看>>
django 目录结构修改
查看>>
win8 关闭防火墙
查看>>
CSS——(2)与标准流盒模型
查看>>
C#中的Marshal
查看>>
linux命令:ls
查看>>
Using RequireJS in AngularJS Applications
查看>>
hdu 2444(二分图最大匹配)
查看>>
【SAP HANA】关于SAP HANA中带层次结构的计算视图Cacultation View创建、激活状况下在系统中生成对象的研究...
查看>>
DevOps 前世今生 | mPaaS 线上直播 CodeHub #1 回顾
查看>>
iOS 解决UITabelView刷新闪动
查看>>
CentOS 7 装vim遇到的问题和解决方法
查看>>
JavaScript基础教程1-20160612
查看>>