进程的表现形式

2024-05-31 17:48
文章标签 进程 表现形式

本文主要是介绍进程的表现形式,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

进程的表现形式

1.进程生命周期

运行:该进程此刻正在执行。

等待:进程能够运行,但没有得到许可,因为CPU分配给另一个进程。调度器可以在下一次
任务切换时选择该进程。

睡眠:进程正在睡眠无法运行,因为它在等待一个外部事件。调度器无法在下一次任务切换
时选择该进程。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cdhbjB9m-1616056708510)(/home/hao/my_work/Learning_set/tools_Lib/all_picture/note/1.jpg)]

2.进程表示

include/linux/sched.h中有结构体struct task_struct;表示了进程的所有信息。

struct task_struct { volatile long state; /* -1表示不可运行,0表示可运行,>0表示停止 */ void *stack; atomic_t usage; unsigned long flags; /* 每进程标志,下文定义 */ unsigned long ptrace; int lock_depth; /* 大内核锁深度 */ int prio, static_prio, normal_prio; struct list_head run_list; const struct sched_class *sched_class; struct sched_entity se; unsigned short ioprio; unsigned long policy; cpumask_t cpus_allowed; unsigned int 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链表是ptrace能够看到的当前进程的子进程列表。*/ struct list_head ptrace_children; struct list_head ptrace_list; struct mm_struct *mm, *active_mm; /* 进程状态 */ struct linux_binfmt *binfmt; long exit_state; int exit_code, exit_signal; int pdeath_signal; /* 在父进程终止时发送的信号 */ unsigned int personality; unsigned did_exec:1; pid_t pid; pid_t tgid; /* * 分别是指向(原)父进程、最年轻的子进程、年幼的兄弟进程、年长的兄弟进程的指针。*(p->father可以替换为p->parent->pid)*/ struct task_struct *real_parent; /* 真正的父进程(在被调试的情况下) */ struct task_struct *parent; /* 父进程 */ /* * children/sibling链表外加当前调试的进程,构成了当前进程的所有子进程*/ struct list_head children; /* 子进程链表 */ struct list_head sibling; /* 连接到父进程的子进程链表 */ struct task_struct *group_leader; /* 线程组组长 */ /* PID与PID散列表的联系。 */ struct pid_link pids[PIDTYPE_MAX]; struct list_head thread_group; struct completion *vfork_done; /* 用于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, utimescaled, stimescaled; unsigned long nvcsw, nivcsw; /* 上下文切换计数 */ struct timespec start_time; /* 单调时间 */ struct timespec real_start_time; /* 启动以来的时间 */ /* 内存管理器失效和页交换信息,这个有一点争论。它既可以看作是特定于内存管理器的,也可以看作是特定于线程的 */ 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]; /* 进程身份凭据 */ 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; char comm[TASK_COMM_LEN]; /* 除去路径后的可执行文件名称-用[gs]et_task_comm访问(其中用task_lock()锁定它)-通常由flush_old_exec初始化 */ /* 文件系统信息 */ int link_count, total_link_count; /* ipc相关 */ struct sysv_sem sysvsem; /* 当前进程特定于CPU的状态信息 */ struct thread_struct thread; /* 文件系统信息 */ struct fs_struct *fs; /* 打开文件信息 */ struct files_struct *files; /* 命名空间 */ struct nsproxy *nsproxy; /* 信号处理程序 */ struct signal_struct *signal; struct sighand_struct *sighand; sigset_t blocked, real_blocked; sigset_t saved_sigmask; /* 用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; #ifdef CONFIG_SECURITY void *security; #endif /* 线程组跟踪 */ u32 parent_exec_id; u32 self_exec_id; /* 日志文件系统信息 */ void *journal_info; /* 虚拟内存状态 */ 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; /* 由ptrace使用。*/ ... 
};

进程限制:

RLIMIT_CPU #按毫秒计算的最大CPU时间
RLIMIT_FSIZE #允许的最大文件长度
RLIMIT_DATA #数据段的最大长度
RLIMIT_STACK #(用户状态)栈的最大长度
RLIMIT_CORE #内存转储文件的最大长度
RLIMIT_RSS #常驻内存的最大尺寸。换句话说,进程使用页帧的最大数目。目前未使用
RLIMIT_NPROC #与进程真正UID关联的用户可以拥有的进程的最大数目
RLIMIT_NOFILE #打开文件的最大数目
RLIMIT_MEMLOCK #不可换出页的最大数目
RLIMIT_AS #进程占用的虚拟地址空间的最大尺寸
RLIMIT_LOCKS #文件锁的最大数目
RLIMIT_SIGPENDING #待决信号的最大数目
RLIMIT_MSGQUEUE #信息队列的最大数目
RLIMIT_NICE #非实时进程的优先级(nice level)
RLIMIT_RTPRIO #最大的实时优先级
命名空间:

概念:就是c++命名空间的意思,隔离资源。

创建:

1.用fork或者clone系统调用创建新进程时,有特定的选项可以控制使用使用新命名空间或者使用父命名空间。

2.unshare系统调用将进程的某些部分与父进程分离,包括命名空间。

进程类中命名空间结构体:

struct nsproxy {atomic_t count;struct uts_namespace *uts_ns;struct ipc_namespace *ipc_ns;struct mnt_namespace *mnt_ns;struct pid_namespace *pid_ns;struct net 	     *net_ns;
};
  • UTS命名空间:
  • ipc命名空间:
  • mnt命名空间:
  • pid命名空间:
  • net命名空间:
进程id号:

​ UNIX进程总是会分配一个号码用于在其命名空间中唯一地标识它们。该号码被称作进程ID号,
简称PID。用fork或clone产生的每个进程都由内核自动地分配了一个新的唯一的PID值。

3.进程的系统调用

fork->sys_fork }

vfork->sys_vfork }---->do_fork

clone->sys_clone }

//arch/x86/kernel/process_32.c 
asmlinkage int sys_clone(struct pt_regs regs) 
{ unsigned long clone_flags; unsigned long newsp; int __user *parent_tidptr, *child_tidptr; clone_flags = regs.ebx; newsp = regs.ecx; parent_tidptr = (int __user *)regs.edx; child_tidptr = (int __user *)regs.edi; if (!newsp) newsp = regs.esp; return do_fork(clone_flags, newsp, &regs, 0, parent_tidptr, child_tidptr); 
}asmlinkage int sys_fork(long r10, long r11, long r12, long r13, long mof, long srp,struct pt_regs *regs)
{//SIGCHLD:子进程结束后,发送SIGCHLD信号给父进程。return do_fork(SIGCHLD, rdusp(), regs, 0, NULL, NULL);
}//kernel/fork.c 
long do_fork(unsigned long clone_flags, unsigned long stack_start,struct pt_regs *regs, unsigned long stack_size, int __user *parent_tidptr, int __user *child_tidptr)
  • clone_flags是一个标志集合,用来指定控制复制过程的一些属性。最低字节指定了在子进程
    终止时被发给父进程的信号号码。其余的高位字节保存了各种常数,下文会分别讨论。
  • stack_start是用户状态下栈的起始地址。
  • regs是一个指向寄存器集合的指针,其中以原始形式保存了调用参数。该参数使用的数据类
    型是特定于体系结构的struct pt_regs,其中按照系统调用执行时寄存器在内核栈上的存储
    顺序,保存了所有的寄存器(更详细的信息,请参考附录A)。
  • stack_size是用户状态下栈的大小。该参数通常是不必要的,设置为0
  • parent_tidptr和child_tidptr是指向用户空间中地址的两个指针,分别指向父子进程的
    PID。NPTL(Native Posix Threads Library)库的线程实现需要这两个参数。我将在下文讨论
    其语义。

核心功能流程:

1.检查标志

2.dup_task_struct

3.检查资源限制

4.初始化task_struct

5.sched_fork

6.复制/共享进程的各个部分。

  • copy_semundo:
  • copy_files:
  • copy_fs:
  • copy_sighand:
  • copy_signal:
  • copy_mm:
  • copy_namespaces:
  • copy_thread:

7.设置各个进程id,进程关系,等等。

这篇关于进程的表现形式的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1018626

相关文章

[Linux]:进程(下)

✨✨ 欢迎大家来到贝蒂大讲堂✨✨ 🎈🎈养成好习惯,先赞后看哦~🎈🎈 所属专栏:Linux学习 贝蒂的主页:Betty’s blog 1. 进程终止 1.1 进程退出的场景 进程退出只有以下三种情况: 代码运行完毕,结果正确。代码运行完毕,结果不正确。代码异常终止(进程崩溃)。 1.2 进程退出码 在编程中,我们通常认为main函数是代码的入口,但实际上它只是用户级

java 进程 返回值

实现 Callable 接口 与 Runnable 相比,Callable 可以有返回值,返回值通过 FutureTask 进行封装。 public class MyCallable implements Callable<Integer> {public Integer call() {return 123;}} public static void main(String[] args

C#关闭指定时间段的Excel进程的方法

private DateTime beforeTime;            //Excel启动之前时间          private DateTime afterTime;               //Excel启动之后时间          //举例          beforeTime = DateTime.Now;          Excel.Applicat

linux中使用rust语言在不同进程之间通信

第一种:使用mmap映射相同文件 fn main() {let pid = std::process::id();println!(

Golang进程权限调度包runtime

关于 runtime 包几个方法: Gosched:让当前线程让出 cpu 以让其它线程运行,它不会挂起当前线程,因此当前线程未来会继续执行GOMAXPROCS:设置最大的可同时使用的 CPU 核数Goexit:退出当前 goroutine(但是defer语句会照常执行)NumGoroutine:返回正在执行和排队的任务总数GOOS:目标操作系统NumCPU:返回当前系统的 CPU 核数量 p

如何保证android程序进程不到万不得已的情况下,不会被结束

最近,做一个调用系统自带相机的那么一个功能,遇到的坑,在此记录一下。 设备:红米note4 问题起因 因为自定义的相机,很难满足客户的所有需要,比如:自拍杆的支持,优化方面等等。这些方面自定义的相机都不比系统自带的好,因为有些系统都是商家定制的,难免会出现一个奇葩的问题。比如:你在这款手机上运行,无任何问题,然而你换一款手机后,问题就出现了。 比如:小米的红米系列,你启用系统自带拍照功能后

flume系列之:记录一次flume agent进程被异常oom kill -9的原因定位

flume系列之:记录一次flume agent进程被异常oom kill -9的原因定位 一、背景二、定位问题三、解决方法 一、背景 flume系列之:定位flume没有关闭某个时间点生成的tmp文件的原因,并制定解决方案在博主上面这篇文章的基础上,在机器内存、cpu资源、flume agent资源都足够的情况下,flume agent又出现了tmp文件无法关闭的情况 二、

C++编程:ZeroMQ进程间(订阅-发布)通信配置优化

文章目录 0. 概述1. 发布者同步发送(pub)与订阅者异步接收(sub)示例代码可能的副作用: 2. 适度增加缓存和队列示例代码副作用: 3. 动态的IPC通道管理示例代码副作用: 4. 接收消息的超时设置示例代码副作用: 5. 增加I/O线程数量示例代码副作用: 6. 异步消息发送(使用`dontwait`标志)示例代码副作用: 7. 其他可以考虑的优化项7.1 立即发送(ZMQ_IM

[轻笔记] ubuntu Shell脚本实现监视指定进程的运行状态,并能在程序崩溃后重启动该程序

根据网上博客实现,发现只能监测进程离线,然后对其进行重启;然而,脚本无法打印程序正常状态的信息。自己通过不断修改测试,发现问题主要在重启程序的命令上(需要让重启的程序在后台运行,不然会影响监视脚本进程,使其无法正常工作)。具体程序如下: #!/bin/bashwhile [ 1 ] ; dosleep 3if [ $(ps -ef|grep exe_name|grep -v grep|

[Linux]:环境变量与进程地址空间

✨✨ 欢迎大家来到贝蒂大讲堂✨✨ 🎈🎈养成好习惯,先赞后看哦~🎈🎈 所属专栏:Linux学习 贝蒂的主页:Betty’s blog 1. 环境变量 1.1 概念 **环境变量(environment variables)**一般是指在操作系统中用来指定操作系统运行环境的一些参数,具有全局属性,可以被子继承继承下去。 如:我们在编写C/C++代码的时,在链接的时候,我们并不知