<4D F736F F D20B5DA35D5C22020B2D9D7F7CFB5CDB3BDF8B3CC>

Size: px
Start display at page:

Download "<4D F736F F D20B5DA35D5C22020B2D9D7F7CFB5CDB3BDF8B3CC>"

Transcription

1 从实践中学嵌入式 LINUX 操作系统 作者 : 华清远见 第 5 章 操作系统进程

2 在计算机使用过程中, 我们经常谈及的概念是程序 作为最终用户, 我们关心系统中哪些程序在运行, 需要关闭哪个程序 但是从操作系统的范畴来说, 我们使用更多的是进程 进程和程序虽然有一定的联系, 但是绝不能混为一谈 在传统的操作系统中, 程序并不能独立运行, 作为资源分配和独立运行的基本单元都是进程 程序是一个普通文件, 是机器代码指令和数据的集合, 这些指令和数据存储在磁盘上的一个可执行映像 (Executable Image) 中 进程是由正文段 (Text) 用户数据段 (User Segment) 及系统数据段 (System Segment) 共同组成的一个执行环境, 它是一个动态实体 程序是硬盘上存放的一个文件 ( 代码 ) 当程序运行时, 它也就成为了进程 进程的组成部分如下 正文段 : 存放被执行的机器指令 这个段是只读的, 它允许系统中正在运行的两个或多个进程之间能够共享这一代码, 但是不能对其内容进行更改 用户数据段 : 存放进程在执行时直接进行操作的所有数据, 包括进程使用的全部变量在内 显然, 这里包含的信息可以被改变 虽然进程之间可以共享正文段, 但是每个进程需要有它自己的专用用户数据段 系统数据段 : 该段有效地存放程序运行的环境 这也是进程和程序不同的一个原因之一 如图 5.1 所示为程序和进程的区别 程序 正文段 用户数据段 进程 系统数据段 5.1 Windows 和 Linux 操作系统都属于多任务系统, 可以同时运行多个进程 我们经常使用的 Windows 任务管理器可以清楚地列出当前系统运行的进程, 如图 5.2 所示, 在图中可以看到, 该系统此时正在运行的进程有 29 个 5.2 Windows - 2 -

3 在谈到进程时, 还要涉及线程的概念 线程是系统分配处理器时间资源的基本单元, 或者说进程之内独立执行的一个单元 对于操作系统来说, 其调度单元是线程 一个进程至少包括一个线程, 通常将该线程称为主线程 一个进程从主线程的执行开始进而创建一个或多个附加线程, 就是所谓基于多线程的多任务 在 Linux 2.6 内核中,Linux 采用了更为先进的线程模型 :NPTL(Native POSIX Thread Library) 与传统的 LinuxThreads 线程模型相比,NPTL 与 POSIX 标准兼容, 并且性能提升明显, 也具备更好的可伸缩性 对 Linux 内核而言, 线程和进程没有本质的区别, 它们都是调度的基本单位 ( 实际上,Linux 内核基于进程机制实现线程 ), 本书重点介绍进程的内容 Linux 进程基础 Linux 进程一般分为交互进程 批处理进程和守护进程 3 类 与 Windows 任务管理器一样, 在 Linux 中可以通过 ps 命令查看系统当前的进程, 例如, 下面的命令将列出系统所有的进程 : [root@localhost ~]# ps -aux 如果进程太多, 可以把 ps 命令的输出保存到一个文件中 : [root@localhost ~]# ps -aux > mypsout ps 是 Linux 进程管理中最重要的一个命令, 它提供了很多选项参数, 如表 5.1 所示 表 5.1 ps 命令的选项参数 参数功能 常用的选项组合是 aux, 使用不同的选项会产生不同的输出结果 表 5.2 列出了使用 ps 命令的输出列说明 表 5.2 ps 的输出列说明列说明 - 3 -

4 表 5.2 中的 STAT 列表示进程的状态 在 Linux 操作系统中, 系统有几种不同的状态, 在 CPU 的调度下, 进行状态的切换 表 5.3 列出了 Linux 系统中的各种进程状态 表 5.3 Linux 进程状态值说明 D R S T W X Z 该进程处于睡眠状态该进程处于运行状态该进程处于睡眠状态该进程处于停止或被追踪状态进入内存交换死掉的进程僵尸进程 < 优先级高的进程 N L s l 优先级较低的进程有些页被锁进内存进程的领导者多线程进程 + 位于后台的进程组 - 4 -

5 5.2.2 进程描述符 Linux 系统的每一个可调度实体都有一个进程描述符 进程描述符可以表示进程的各种状态信息, 是内核操作进程的手段 进程描述符用 task_struct 数据结构表示, 该结构包含一个进程所拥有的各种信息, 非常庞大, 在内核文件的 sched.h 中定义 下面给出 task_struct 数据结构的片断 struct task_struct volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */ void *stack; atomic_t usage; unsigned int flags; /* per process flags, defined below */ unsigned int ptrace; int lock_depth; /* BKL lock depth */ int prio, static_prio, normal_prio; unsigned int rt_priority; const struct sched_class *sched_class; struct sched_entity se; struct sched_rt_entity rt; unsigned char fpu_counter; s8 oomkilladj; /* OOM kill score adjustment (bit shift). */ unsigned int policy; cpumask_t cpus_allowed; struct list_head tasks; struct mm_struct *mm, *active_mm; /* task state */ struct linux_binfmt *binfmt; int exit_state; int exit_code, exit_signal; int pdeath_signal; /* The signal sent when the parent dies */ unsigned int personality; unsigned did_exec:1; pid_t pid; pid_t tgid; struct task_struct *real_parent; /* real parent process */ struct task_struct *parent; /* recipient of SIGCHLD, wait4() reports */ 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 */ struct list_head ptraced; struct list_head ptrace_entry; /* 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 */ cputime_t utime, stime, utimescaled, stimescaled; cputime_t gtime; cputime_t prev_utime, prev_stime; unsigned long nvcsw, nivcsw; /* context switch counts */ struct timespec start_time; /* monotonic time */ struct timespec real_start_time; /* boot based time */ unsigned long min_flt, maj_flt; struct task_cputime cputime_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, cap_bset; struct user_struct *user; unsigned securebits; /* file system info */ - 5 -

6 int link_count, total_link_count; #ifdef CONFIG_SYSVIPC /* ipc stuff */ struct sysv_sem sysvsem; #endif #ifdef CONFIG_DETECT_SOFTLOCKUP /* hung task detection */ unsigned long last_switch_timestamp; unsigned long last_switch_count; #endif /* CPU-specific state of this task */ struct thread_struct thread; /* filesystem information */ struct fs_struct *fs; /* open file information */ struct files_struct *files; /* namespaces */ struct nsproxy *nsproxy; /* signal handlers */ struct signal_struct *signal; struct sighand_struct *sighand; sigset_t blocked, real_blocked; sigset_t saved_sigmask; /* restored if set_restore_sigmask() was used */ struct sigpending pending; unsigned long sas_ss_sp; size_t sas_ss_size; int (*notifier)(void *priv); void *notifier_data; sigset_t *notifier_mask; 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; /* journalling filesystem info */ void *journal_info; /* stacked block device info */ struct bio *bio_list, **bio_tail; atomic_t fs_excl; /* holding fs exclusive resources */ struct rcu_head rcu; unsigned long timer_slack_ns; unsigned long default_timer_slack_ns; ; struct list_head *scm_work_list; 在这个结构中, 对一个进程进行了全面描述 例如, 每一个进程都有自己的进程号, 该数字在系统中是唯一的, 它存放在进程描述符的成员变量 pid 中 : pid_t pid; 同样, 线程组号存放在成员变量 tgid 中 : pid_t tpid; 这个结构大致可以分为以下几类 : 进程状态 记录进程是在等待 运行还是死锁 调度信息 由哪个调度函数调度, 怎样调度等 进程的通信状况 因为要插入进程树, 所以必须有联系父子兄弟的指针 时间信息 如计算好执行的时间, 以便 CPU 分配 - 6 -

7 标号 决定改进程归属 可以读 / 写打开的一些文件信息 进程上下文和内核上下文 处理器上下文 内存信息 进程的状态与转换 进程对系统资源的竞争和进程之间的并发执行, 使得一个进程在从创建到销毁的这个生命周期内要经历各种不同状态的变化 一个进程的各种状态在 task_struct 结构中通过成员变量 state exit_state 记录 那么内核究竟为进程定义了几种状态? 我们可以通过查看 sched.h 文件中定义的宏查找到答案 #define TASK_RUNNING 0 #define TASK_INTERRUPTIBLE 1 #define TASK_UNINTERRUPTIBLE 2 #define TASK_STOPPED 4 #define TASK_TRACED 8 /* in tsk->exit_state */ #define EXIT_ZOMBIE 16 #define EXIT_DEAD 32 /* in tsk->state again */ #define TASK_DEAD 64 #define TASK_WAKEKILL 128 其中各个状态的含义如下 TASK_RUNNING: 表示进程正在运行, 或者是进程获得了除处理器以外的全部资源, 一旦获得处理器, 即可运行 TASK_INTERRUPTIBLE: 表示进程处于阻塞态, 处于该状态的进程睡眠在相应资源的等待队列上, 当该类资源再次有效时, 系统会唤醒进程, 并转换到运行态 (TASK_RUNNING) TASK_UNINTERRUPTIBLE: 与 TASK_INTERRUPTIBLE 态相似, 不同的是, 该状态下的进程一直等待, 直到所需要的资源有效或等待超时从而由系统唤醒 TASK_STOPPED: 表示进程处于暂停状态, 通过任务控制信号 SIGSTOP 可以将 TASK_RUNNING 状态的进程转换到此状态 ; 在此状态下的进程收到 SIGCONT 信号后会转换到 TASK_RUNNING 状态 TASK_TRACED: 表示该进程处于监控状态, 用于程序的 BUG 调试 EXIT_ZOMBIE: 表示进程处于僵尸状态, 在这个状态下的进程只能转换到 EXIT_DEAD 状态 僵尸状态的产生是由于父进程死亡而被终止的进程, 但是在 task 数据中仍然保留 task_struct 结构 EXIT_DEAD: 表示父进程已经获得了该进程的记账信息, 该进程可以被销毁 TASK_WAKEKILL: 表示该进程已经退出且不需要父进程来回收 提示 在 Linux 的 内核中, 引入了一种新的进程状态 :TASK_KILLABLE, 它用于将进程置为睡眠状态, 可以替代有效但可能无法终止的 TASK_UNINTERRUPTIBLE 进程状态, 以及易于唤醒但更加安全的 TASK_INTERRUPTIBLE 进程状态 但是在更高版本的内核中,Linux 又引入了 TASK_WAKEKILL 状态, 随着这个状态的出现, 内核又定义了几个便于设置状态的宏 : /* Convenience macros for the sake of set_task_state */ #define TASK_KILLABLE (TASK_WAKEKILL TASK_UNINTERRUPTIBLE) #define TASK_STOPPED (TASK_WAKEKILL TASK_STOPPED) #define TASK_TRACED (TASK_WAKEKILL TASK_TRACED) /* Convenience macros for the sake of wake_up */ - 7 -

8 #define TASK_NORMAL #define TASK_ALL (TASK_INTERRUPTIBLE TASK_UNINTERRUPTIBLE) (TASK_NORMAL TASK_STOPPED TASK_TRACED) /* get_task_state() */ #define TASK_REPORT (TASK_RUNNING TASK_INTERRUPTIBLE \ TASK_UNINTERRUPTIBLE TASK_STOPPED \ TASK_TRACED) 通过上面的代码, 读者应该会更清楚 TASK_STOPPED 和 TASK_STOPPED 的区别了 Linux 系统通过一系列机制, 每个进程的状态不断转换, 从而实现多任务同时进行, 其状态转换图如图 5.3 所示 获得 CPU 而正在运行的进程若申请不到某个资源, 则调用 sleep_on() 或 interruptible_sleep_on() 睡眠, 其 task_struct 挂到相应的等待队列 如果调用 sleep_on() 睡眠, 则其状态变为 TASK_UNINTERRUPTIBLE 如果调用 interruptible_sleep_on() 睡眠, 则其状态变为 TASK_INTERRUPTIBLE sleep_on() 或 interruptible_sleep_on() 将调用 schedule() 函数把睡眠进程释放的 CPU 分配给 run-queue 队列的某个就绪进程 状态为 TASK_INTERRUPTIBLE 的睡眠进程当申请的资源有效时被唤醒 ( 如 wake_up_interruptible()), 也可以由信号 (signal) 或定时中断唤醒 而状态为 TASK_UNINTERRUPTIBLE 的睡眠进程只有当它申请的资源有效时才能被唤醒 ( 如 wake_up()), 不能被信号 (Signal) 定时中断唤醒 唤醒后, 进程状态改为 TASK_RUNNING, 并进入运行队列 进程执行系统调用 sys_exit() 或收到 SIG_KILL 信号而调用 do_exit() 时, 进程状态变为 TASK_ZOMBIE, 释放所申请的资源, 同时启动 schedule() 把 CPU 分配给运行队列中其他就绪进程 若进程通过系统调用设置 PF_SYSTRACE, 则在系统调用返回前, 进入 ptrace(), 状态变为 TASK_STOPPED,CPU 分配给运行队列中其他就绪进程 只有通过其他进程发送 SIG_KILL 或 SIG_CONT, 才能把 TASK_STOPPED 进程唤醒, 重新进入运行队列 fork() 收到信号 SIGCONT wake_up() 资源到位 wake_up() TASK_RUNNING 资源到位 wake_up_interruptible() 或收到信号 wake_up() schedule() 时间片耗尽 TASK_INTERRUPTIBLE TASK_UNINTERRUPTIBLE 等待资源到位 sleep_on() schedule() 占有 CPU 等待资源到位 interruptible_sleep_on() schedule() TASK_STOPPED schedule() ptrace() do_exit() TASK_ZOMBIE 5.3 Linux 进程队列指针 为了有效地管理系统中的每个进程, 需要采用一种高效的数据结构把系统内全部进程组织起来 当需要进程的信息时, 可以从该结构中查找到相关进程 Linux 的所有进程组成一个双向链表, 在内核中的类型是 struct list_head 的成员变量 tasks: struct list_head tasks; 注意 - 8 -

9 list_head 结构体在 include/linux/list.h 文件中定义, 代码如下 : struct list_head struct list_head *next, *prev; ; include/linux/list.h 文件中提供了用来操作该链表的函数和宏, 它们实现了对链表的插入 删除 转移 合并 遍历 这些函数和宏比较简单, 这里不再详细分析 static inline void list_add(struct list_head *new, struct list_head *head) static inline void list_add_tail(struct list_head *new, struct list_head *head) static inline void list_replace(struct list_head *old,struct list_head *new) static inline void list_replace_init(struct list_head *old,struct list_head *new) static inline void list_del_init(struct list_head *entry) static inline void list_move(struct list_head *list, struct list_head *head) static inline void list_move_tail(struct list_head *list,struct list_head *head) static inline int list_is_last(const struct list_head *list,const struct list_head *head) static inline int list_empty(const struct list_head *head) static inline void list_splice(const struct list_head *list,struct list_head *head) static inline void list_splice_tail(struct list_head *list,struct list_head *head) static inline void list_splice_init(struct list_head *list,struct list_head *head) static inline void list_splice_tail_init(struct list_head *list,struct list_head *head) #define list_entry(ptr, type, member) \ container_of(ptr, type, member) #define list_first_entry(ptr, type, member) \ list_entry((ptr)->next, type, member) #define list_for_each(pos, head) \ for (pos = (head)->next; pos!= (head); pos = pos->next) #define list_for_each_prev(pos, head) \ for (pos = (head)->prev; prefetch(pos->prev), pos!= (head); \ pos = pos->prev) #define list_for_each_safe(pos, n, head) \ for (pos = (head)->next, n = pos->next; pos!= (head); \ pos = n, n = pos->next) #define list_for_each_prev_safe(pos, n, head) \ for (pos = (head)->prev, n = pos->prev; \ prefetch(pos->prev), pos!= (head); \ pos = n, n = pos->prev) #define list_for_each_entry(pos, head, member) \ for (pos = list_entry((head)->next, typeof(*pos), member); \ prefetch(pos->member.next), &pos->member!= (head); \ pos = list_entry(pos->member.next, typeof(*pos), member)) #define list_for_each_entry_reverse(pos, head, member) \ for (pos = list_entry((head)->prev, typeof(*pos), member); \ prefetch(pos->member.prev), &pos->member!= (head); \ pos = list_entry(pos->member.prev, typeof(*pos), member)) #define list_prepare_entry(pos, head, member) \ ((pos)? : list_entry(head, typeof(*pos), member)) #define list_for_each_entry_continue(pos, head, member) \ for (pos = list_entry(pos->member.next, typeof(*pos), member); \ prefetch(pos->member.next), &pos->member!= (head); \ pos = list_entry(pos->member.next, typeof(*pos), member)) #define list_for_each_entry_continue_reverse(pos, head, member) \ for (pos = list_entry(pos->member.prev, typeof(*pos), member); \ prefetch(pos->member.prev), &pos->member!= (head); \ pos = list_entry(pos->member.prev, typeof(*pos), member)) #define list_for_each_entry_from(pos, head, member) \ for (; prefetch(pos->member.next), &pos->member!= (head); \ pos = list_entry(pos->member.next, typeof(*pos), member)) #define list_for_each_entry_safe(pos, n, head, member) \ - 9 -

10 for (pos = list_entry((head)->next, typeof(*pos), member), \ n = list_entry(pos->member.next, typeof(*pos), member); \ &pos->member!= (head); \ pos = n, n = list_entry(n->member.next, typeof(*n), member)) #define list_for_each_entry_safe_continue(pos, n, head, member) \ for (pos = list_entry(pos->member.next, typeof(*pos), member), \ n = list_entry(pos->member.next, typeof(*pos), member); \ &pos->member!= (head); \ pos = n, n = list_entry(n->member.next, typeof(*n), member)) #define list_for_each_entry_safe_from(pos, n, head, member) \ for (n = list_entry(pos->member.next, typeof(*pos), member); \ &pos->member!= (head); \ pos = n, n = list_entry(n->member.next, typeof(*n), member)) #define list_for_each_entry_safe_reverse(pos, n, head, member) \ for (pos = list_entry((head)->prev, typeof(*pos), member), \ n = list_entry(pos->member.prev, typeof(*pos), member); \ &pos->member!= (head); \ pos = n, n = list_entry(n->member.prev, typeof(*n), member)) 内核提供了宏 for_each_process, 可以方便地搜索所有进程 当需要对系统中每一个进程进行操作时, 该宏定义非常有用 它也在 sched.h 文件中定义, 代码如下 : #define next_task(p) list_entry(rcu_dereference((p)->tasks.next), struct task_ struct, tasks) #define for_each_process(p) \ for (p = &init_task ; (p = next_task(p))!= &init_task ; ) 其中,init_task 是系统初始化过程中创建的第一个进程的进程描述符 (PID), 通过 list_entry() 函数找到 task_struct 的地址, 这样就可以打印进程的 PID 等域 下面通过一个例子, 进一步了解 list_head 结构的使用 下面的程序利用 list_head 结构遍历系统中的全部进程 static int hello_init(void) struct task_struct *task,*p; struct list_head *pos; int count=0; printk("hello World\n"); task=&init_task; list_for_each(pos,&task->tasks) p=list_entry(pos, struct task_struct, tasks); count++; printk("%d-->%s\n",p->pid,p->comm); printk("total process is:%d\n",count); return 0; static void hello_exit(void) printk( "Bye world!\n"); module_init(hello_init); module_exit(hello_exit); 进程队列的全局变量 在 Linux 中, 内核使用 current 变量表示当前正在运行的进程 current 是一个 task_struct 类型的全局变量 下面的语句可以打印当前进程 printk( "Current task is %s [%d], current->comm, current->pid ); 打开 arch/arm/include/asm/current.h 头文件, 可以了解到 current 只是一个宏定义 : static inline struct task_struct *get_current(void) attribute_const ; static inline struct task_struct *get_current(void)

11 return current_thread_info()->task; #define current (get_current()) current_thread_info 函数用来获得当前进程的地址信息, 代码及解释如下 : static inline struct thread_info *current_thread_info(void) register unsigned long sp asm ("sp"); return (struct thread_info *)(sp & ~(THREAD_SIZE - 1)); 在 ARM 平台中, 内核栈是 8KB, 在栈顶 ( 最低地址 ) 处存放了一个指向当前进程的 task_struct 的指针, 而 sp 就是当前的内核态堆栈指针, 把它和 ~8191 进行 与 操作 ( 清空最后 13 位 ), 即获得栈顶的地址 然后把里面的值赋给 current, 这样 current 就得到了当前 task_struct 的指针 THREAD_SIZE 在 thread_info.h 文件中有定义如下 : #define THREAD_SIZE 8192 #define THREAD_START_SP (THREAD_SIZE - 8) thread_info.h 文件中定义的 thread_info 结构如下 : struct thread_info struct task_struct *task; /* main task structure */ struct exec_domain *exec_domain;/* execution domain */ unsigned long flags; /* low level flags */ u32 cpu; /* current CPU */ int preempt_count; /* 0 => preemptable,<0 => BUG */ mm_segment_t addr_limit; /* thread address space: 0-0xBFFFFFFF for user 0-0xFFFFFFFF for kernel */ struct restart_block restart_block; struct thread_info *real_thread; /* Points to non-irq stack */ ; 其实 thread_info 结构的第一个成员就是一个指向 task_struct 结构的指针, 所以要用 current_thread_info()->task 表示 task_struct 的地址, 但是整个过程对用户是完全透明的, 我们还是可以用 current 表示当前进程 一个进程不会平白无故地诞生, 它总会有自己的 父母 在 Linux 中, 通过调用 fork 系统调用来创建一个新的进程 新创建的子进程同样也能执行 fork, 所以, 有可能形成一颗完整的进程树 注意, 每个进程只有一个父进程, 但可以有 0 个 1 个 2 个或多个子进程 图 5.4 描述了 Linux 进程层次结构 其中, Pa 和 Pb 是进程 P 的两个子进程, 而 Pc 和 Pd 又是进程 Pa 的两个子进程 P P P P P P 5.4 Linux Linux 在启动时就创建一个称为 init 的特殊进程, 其进程标识符 (PID) 为 1, 它是用户态下所有进程的祖先进程, 以后诞生的所有进程都是它的子进程 或是它的儿子, 或是它的孙子 1 号进程运行时查

12 询系统当前存在的终端数, 然后为每个终端创建一个新的管理进程, 这些进程在终端上等待着用户的登录 当用户正确登录后, 系统再为每一个用户启动一个 Shell 进程, 由 Shell 进程等待并接受用户输入的命令 应用程序可以通过 fork vfork 或 clone 函数建立新的用户线程, 这些函数分别通过系统调用访问 sys_fork sys_vfork, 或 sys_clone 内核函数建立新线程, 而 sys_fork sys_vfork 与 sys_clone 共同的调用函数为 do_fork sys_fork 和 sys_vfork 在 arch/um/kernel/syscall.c 文件中实现,sys_clone 函数在 arch/um/sys-i386/syscall.c 文件中实现, 代码如下 : long sys_fork(void) long ret; current->thread.forking = 1; ret = do_fork(sigchld, UPT_SP(&current->thread.regs.regs), &current->thread.regs, 0, NULL, NULL); current->thread.forking = 0; return ret; long sys_vfork(void) long ret; current->thread.forking = 1; ret = do_fork(clone_vfork CLONE_VM SIGCHLD, UPT_SP(&current->thread.regs.regs), &current->thread.regs, 0, NULL, NULL); current->thread.forking = 0; return ret; long sys_clone(unsigned long clone_flags, unsigned long newsp, int user *parent_tid, void *newtls, int user *child_tid) long ret; if (!newsp) newsp = UPT_SP(&current->thread.regs.regs); current->thread.forking = 1; ret = do_fork(clone_flags, newsp, &current->thread.regs, 0, parent_tid, child_tid); current->thread.forking = 0; return ret; Linux 创建进程的函数的层次结构如图 5.5 所示 vfork() fork() 用户空间 sys_vfork() sys_fork() sys_clone() do_fork() kernel_thread() copy_process() 内核空间

13 从图 5.5 中可以看到,do_fork 函数是进程创建的基础, 处理 clone fork vfork 系统调用 do_fork 使用辅助函数 copy_process 建立进程描述符及内核数据结构 可以在 kernel/fork.c 文件内找到 do_fork 函数原型 (copy_process 函数也在该文件中 ) long do_fork(unsigned long clone_flags, // 克隆标识 unsigned long stack_start, // 栈起始位置 // 指向通用寄存器值的指针, 通用寄存器的值是在用户态切换到内核态时保存到内核态堆栈 struct pt_regs *regs, unsigned long stack_size, // 栈大小, 一般设置为 0 int user *parent_tidptr, // 父进程用户态变量地址 int user *child_tidptr) // 子进程用户态变量地址 do_fork 函数中比较重要的有两个部分, 首先是给子进程分配进程号, 然后利用具体的进程号创建子进程 下面对这个函数进行简要分析 struct task_struct *p; // 进程描述符 int trace = 0; long nr; if (unlikely(clone_flags & CLONE_STOPPED)) static int read_mostly count = 100; if (count > 0 && printk_ratelimit()) char comm[task_comm_len]; count--; printk(kern_info "fork(): process `%s' used deprecated " "clone flags 0x%lx\n", get_task_comm(comm, current), clone_flags & CLONE_STOPPED); 在 2.6 内核中随处可以看到 likely() 和 unlikely() 宏, 这两个宏在内核中定义如下 : #define likely(x) builtin_expect(!!(x), 1) #define unlikely(x) builtin_expect(!!(x), 0) builtin_expect() 是 GCC (version>=2.96) 提供给程序员使用的, 目的是将 分支转移 的信息提供给编译器, 这样, 编译器就可以对代码进行优化, 以减少指令跳转带来的性能下降 builtin_expect((x),1) 表示 x 的值为真的可能性更大 builtin_expect((x),0) 表示 x 的值为假的可能性更大 也就是说, 使用 likely(), 执行 if 后面的语句的机会更大 ; 使用 unlikely(), 执行 else 后面的语句的机会更大 回到 do_fork 函数中,CLONE_STOPPED 位表示设置进程为停止状态 ( 类似的 clone 标志位在 sched.h 中定义 ), 因此, 为假的可能性更大 随后内核会通过 get_task_comm 函数获得当前进程 (current) 的命令名, 显示给用户 if (likely(user_mode(regs))) trace = tracehook_prepare_clone(clone_flags); 上面的代码检查子进程是否为内核线程, 如果不是, 则将 clone_flags 设为 0 p = copy_process(clone_flags, stack_start, regs, stack_size, child_tidptr, NULL, trace); 随后内核调用 copy_process 函数复制进程描述符 如果成功, 该函数将返回刚创建的 task_struct 描述符的地址 if (!IS_ERR(p)) struct completion vfork; //completion 同步机制 trace_sched_process_fork(current, p); nr = task_pid_vnr(p); // 获得 PID if (clone_flags & CLONE_PARENT_SETTID) put_user(nr, parent_tidptr); if (clone_flags & CLONE_VFORK)

14 p->vfork_done = &vfork; init_completion(&vfork); audit_finish_fork(p); tracehook_report_clone(trace, regs, clone_flags, nr, p); 上面的语句判断是否设置 CLONE_VFORK 标志, 如果设置, 则初始化进程描述符的 vfork_done 标志, 然后初始化 completion p->flags &= ~PF_STARTING; if (unlikely(clone_flags & CLONE_STOPPED)) /* * We'll start up with an immediate SIGSTOP. */ sigaddset(&p->pending.signal, SIGSTOP); set_tsk_thread_flag(p, TIF_SIGPENDING); set_task_state(p, TASK_STOPPED); else wake_up_new_task(p, clone_flags); tracehook_report_clone_complete(trace, regs,clone_flags, nr, p); 如果子进程被跟踪或子进程初始化成 STOP 状态, 则发送 SIGSTOP 信号 由于子进程现在还没有运行, 信号不能被处理, 所以设置 TIF_SIGPENDING 标志 ; 如果设置了 CLONE_STOPPED 标志或必须跟踪子进程, 则将子进程的状态设置为 TASK_STOPPED, 并为子进程增加挂起的 SIGSTOP 信号 ; 如果没有设置 CLONE_STOPPED 标志, 则调用 wake_up_new_task 函数来处理父进程和子进程 if (clone_flags & CLONE_VFORK) freezer_do_not_count(); wait_for_completion(&vfork); freezer_count(); tracehook_report_vfork_done(p, nr); else nr = PTR_ERR(p); return nr; 如果设置了 CLONE_VFORK 标志, 则挂起父进程直到子进程释放自己的内存地址空间, 也就是说, 直到子进程结束或执行新的程序 wait_for_completion(&vfork) 用来等待子进程释放自己的内存地址空间 由于 Linux 以分裂的方法来创建新进程, 这样就使得系统中的所有进程都有亲属关系, 这种亲属关系也会给进程的运行带来一定的影响 为了表示一个进程的亲属关系, 每个进程控制块中都有记录这些亲属关系的成员, 代码如下所示 : struct task_struct struct task_struct *real_parent; /* 父进程 */ struct task_struct *parent; /* 养父进程 */ /* * children/sibling forms the list of my natural children */ struct list_head children; /* 子进程列表 */ struct list_head sibling; /* linkage in my parent's children list */ ; 从内核代码中可以看到, 进程有父进程和养父进程 那么养父进程是什么呢?

15 当一个进程被创建出来以后, 其控制块中的指针 real_parent 和 parent 都指向同一个进程 父进程 但是当其他某个进程通过系统调用 ptrace() 跟踪这个进程时, 被跟踪进程的 parent 会指向这个跟踪进程, 而这个跟踪进程也有指针指向被跟踪进程, 以便通过这个指针得到被跟踪进程的控制块以获得被跟踪进程的信息, 所以这个跟踪进程有些类似 监管人, 因此这个进程也称为 养父 进程 execve() 系统调用 Linux 提供了 execl execlp execle execv execvp 和 execve 共 6 个用以执行一个可执行文件的函数 ( 统称为 exec 函数 ) 这些函数的不同之处在于对命令行参数和环境变量参数的传递方式不同 每个函数的第一个参数都是要被执行的程序的路径, 第二个参数则向程序传递了命令行参数, 第三个参数则向程序传递环境变量 以上函数的本质都是调用 arch/x86/kernel/process.c 文件中实现的系统调用 sys_execve 来执行一个可执行文件, 该函数代码如下 : long sys_execve(char user *name, char user * user *argv,char user * user *envp, struct pt_regs *regs) long error; char *filename; filename = getname(name); error = PTR_ERR(filename); if (IS_ERR(filename)) return error; error = do_execve(filename, argv, envp, regs); #ifdef CONFIG_X86_32 if (error == 0) /* Make sure we don't return using sysenter.. */ set_thread_flag(tif_iret); #endif putname(filename); return error; 从函数原型提供的参数可以看出, 这个函数接收的参数都来自用户空间 在 sys_execve 中调用了 execve 函数, 该函数也在 arch/um/kernel/exec.c 中实现 从下面的代码中可以了解到,execve 实质上调用了 do_execve 函数 int do_execve(char * filename, char user * user *argv, char user * user *envp, struct pt_regs * regs) struct linux_binprm *bprm; struct file *file; struct files_struct *displaced; bool clear_in_exec; int retval; retval = unshare_files(&displaced); if (retval) goto out_ret; retval = -ENOMEM; bprm = kzalloc(sizeof(*bprm), GFP_KERNEL); if (!bprm) goto out_files; retval = prepare_bprm_creds(bprm); if (retval) goto out_free;

16 retval = check_unsafe_exec(bprm); if (retval < 0) goto out_free; clear_in_exec = retval; current->in_execve = 1; file = open_exec(filename); retval = PTR_ERR(file); if (IS_ERR(file)) goto out_unmark; sched_exec(); bprm->file = file; bprm->filename = filename; bprm->interp = filename; retval = bprm_mm_init(bprm); if (retval) goto out_file; bprm->argc = count(argv, MAX_ARG_STRINGS); if ((retval = bprm->argc) < 0) goto out; bprm->envc = count(envp, MAX_ARG_STRINGS); if ((retval = bprm->envc) < 0) goto out; retval = prepare_binprm(bprm); if (retval < 0) goto out; retval = copy_strings_kernel(1, &bprm->filename, bprm); if (retval < 0) goto out; bprm->exec = bprm->p; retval = copy_strings(bprm->envc, envp, bprm); if (retval < 0) goto out; retval = copy_strings(bprm->argc, argv, bprm); if (retval < 0) goto out; current->flags &= ~PF_KTHREAD; retval = search_binary_handler(bprm,regs); if (retval < 0) goto out; /* execve succeeded */ current->fs->in_exec = 0; current->in_execve = 0; acct_update_integrals(current); free_bprm(bprm); if (displaced) put_files_struct(displaced); return retval; out: if (bprm->mm) mmput (bprm->mm); out_file: if (bprm->file)

17 allow_write_access(bprm->file); fput(bprm->file); out_unmark: if (clear_in_exec) current->fs->in_exec = 0; current->in_execve = 0; out_free: free_bprm(bprm); out_files: if (displaced) reset_files_struct(displaced); out_ret: return retval; 上述代码中有两个函数 :copy_strings_kernel 和 copy_strings copy_strings 把参数及执行的环境从用户空间复制到内核空间的 bprm 变量中, 而调用 copy_strings_kernel() 从内核空间中复制文件名 这里还提到了 linux_binfmt 数据结构 (/include/linux/binfmt.h), 它用来支持各种文件系统, 所以 Linux 中的 exec() 函数在执行时, 使用已注册的 linux_binfmt 结构就可以支持不同的二进制格式, 即多种文件系统 (Ext3 FAT 等 ) 需要指出的是,binux_binfmt 结构中嵌入了两个指向函数的指针, 一个指针指向可执行代码, 另一个指向库函数 ; 使用这两个指针是为了装入可执行代码和要使用的库 linux_binfmt 结构描述如下 : struct linux_binprm char buf[binprm_buf_size]; #ifdef CONFIG_MMU struct vm_area_struct *vma; #else # define MAX_ARG_PAGES 32 struct page *page[max_arg_pages]; #endif struct mm_struct *mm; unsigned long p; /* current top of mem */ unsigned int sh_bang:1, misc_bang:1; #ifdef alpha unsigned int taso:1; #endif unsigned int recursion_depth; struct file * file; int e_uid, e_gid; kernel_cap_t cap_post_exec_permitted; bool cap_effective; void *security; int argc, envc; char * filename; /* Name of binary as seen by procps */ char * interp; /* Name of the binary really executed. Most of the time same as filename, but could be different for binfmt_misc,script */ unsigned interp_flags; unsigned interp_data; unsigned long loader, exec; ; 在 do_execve 函数中有一个参数值得我们注意 *regs 它是 pt_regs 类型的数据结构, 该参数描述了在执行该系统调用时, 用户态下的 CPU 寄存器在核心态的栈中的保存情况 通过这个参数,sys_execve 能获得保存在用户空间的以下信息 : 可执行文件路径的指针 (regs.ebx 中 ) 命令行参数的指针(regs.ecx 中 ) 和环境变量的指针 (regs.edx 中 ) 代码如下: struct pt_regs

18 ; long ebx; long ecx; long edx; long esi; long edi; long ebp; long eax; int xds; int xes; int xfs; /* int gs; */ long orig_eax; long eip; int xcs; long eflags; long esp; int xss; 回顾 do_execve(), 它的工作流程如下 : (1) 按参数 filename 找到相关文件的节点, 保存与文件相关的数据, 并检查它的存取权限 (2) 检查文件格式, 并找到能打开这种格式的装载函数 (3) 确认文件的可执行权限后, 首先放弃子进程继承自父进程的虚拟空间结构, 调用 do_mmap() 函数, 根据文件中的虚拟地址信息建立自己的虚拟空间描述结构, 建立空页表, 并使其映射到子进程的进程虚拟地址空间 (4) 创建运行环境 (5) 在子进程运行过程中, 由 Linux 的请页机制逐步为其分配所需要的物理内存空间 下面看一个运行子进程的程序 #include <stdio.h> #include <unistd.h> #include <sys/types.h> int main() char * argu_list[]="ls","/","-l",null; int status=0; pid_t child_pid=fork(); if(child_pid==0) // 子进程 execvp("ls",argu_list); fprintf(stderr,"exec ls error\n"); exit(1); else wait(&status); if(wifexited(status)) printf("the child process exit normally.\n"); else printf("the child process exit abnormally.\n"); exit(0); wait() 系统调用 为了方便用户处理父进程与子进程之间的一些事物,Linux 允许父进程在创建了进程之后, 通过调用 wait() 先进入等待状态, 以使子进程先运行, 然后再决定自己的进一步行为, 这种方式称为父进程的阻塞方式 那么,wait() 在什么时候用呢? 在一些情况下, 父进程可能比子进程结束得要早 如果父进程提前结束

19 了, 子进程就变成了僵尸进程 我们需要父进程来清理子进程结束后的一些环境 这时调用 wait, 父进程将阻塞在 wait() 处, 等待子进程结束 exit() 系统调用进程的结束可以用 exit() 或 _exit() 系统调用 无论在程序中的什么位置, 只要执行到 exit 系统调用, 进程就会停止剩下的所有操作, 清除包括 PCB 在内的各种数据结构, 并终止本进程的运行 对系统调用而言, _exit 和 exit 是一对孪生兄弟, 它们最大的区别就在于 exit() 函数在调用之前要检查文件的打开情况, 把文件缓冲区中的内容写回文件 ; 而 _exit() 直接使进程停止运行, 清除其使用的内存空间, 并销毁其在内核中的各种数据结构, 如图 5.6 所示 进程运行 _exit() 调用退出处理函数 清理 I/O 缓冲 exit() 调用 exit 系统调用 Linux 内核 5.6 exit _exit 下面通过一个简单的程序了解一下 exit 系统调用的用法 main() printf("process will be exit!\n"); exit(0); printf("you cannot see this line!\n"); 编译运行该程序可以看到, 程序并没有打印后面的 You cannot see this line!, 因为在此之前, 在执行到 exit(0) 时, 进程就已经终止了 操作系统的职能之一是管理并调度系统中的进程, 而衡量一个操作系统的关键之一就是调度算法 一个优秀的调度算法能够充分而高效地利用系统资源 存在于 Linux 中的进程通过 Linux 调度程序被调度 每个进程的调度策略在 task_struct 中规定 (policy 属性 ),Linux 内核提供的调度策略类型如表 5.4 所示 其中,SCHED_FIFO 和 SCHED_RR 的优先级高于所有 SCHED_NORMAL 的进程 提示 表 5.4 Linux 进程调度策略 调度策略 采用的调度算法 SCHED_NORMA L 非实时, 基于优先级的轮转法

20 SCHED_FIFO SCHED_RR SCHED_BATCH SCHED_ISO SCHED_IDLE 实时, 先进先出算法 实时, 基于优先级的轮转法 与 SCHED_NORMAL 类似, 该调度算法将使得调度器假定进程对 CPU 时间要求较多 目前还没有实现 进程优先级降为最低 为了实现进程的调度, 每一个多任务操作系统都会为不同的任务分配一个任务优先级, 进程之间是竞争资源 ( 如 CPU 和内存的占用 ) 关系, 这个竞争优劣是通过一个数值来实现的, 也就是谦让度 高谦让度表示进程优先级别最低, 负值或 0 表示高优先级, 对其他进程不谦让, 也就是拥有优先占用系统资源的权力 谦让度的值从 -20 到 19 目前, 硬件技术发展迅速, 大多情况下不必设置进程的优先级, 除非在进程失控而疯狂占用资源的情况下, 才设置优先级 在迫不得已的情况下, 可以杀掉失控进程 Linux 系统提供了 nice 命令来完成进程优先级调整 例如, 下面的命令将运行 vim 程序, 并为它指定谦让度增量为 6: [root@localhost ~]# nice n 6 vim nice 的最常用的应用包括 : nice -n 谦让度的增量值程序 renice 是通过进程 ID(PID) 来改变谦让度, 进而达到更改进程的优先级 renice 谦让度 PID renice 所设置的谦让度就是进程的绝对值 2.6 版本的 Linux 内核提供了 140 个优先级, 后 40 个和 nice 值一一对应, 属于 SCHED_NORMAL 调度策略, 前 100 个属于 SCHED_FIFO 和 SCHED_RR 策略 在调度算法的实现上,Linux 中的每个任务有 4 个与调度相关的参数, 它们是 rt_priority policy priority (nice) counter 调度程序根据这 4 个参数进行进程调度 在 SCHED_NORMAL 调度策略中, 调度器总是选择那个 priority+counter 值最大的进程来调度执行 从逻辑上进行分析,SCHED_NORMAL 调度策略存在着调度周期 (epoch), 在每一个调度周期中, 一个进程的 priority 和 counter 值的大小影响了当前时刻应该调度哪一个进程来执行, 其中 priority 是一个固定不变的值, 在进程创建时就已经确定了, 它代表该进程的优先级, 也代表该进程在每一个调度周期中能够得到的时间片的多少 ;counter 是一个动态变化的值, 它反映了一个进程在当前的调度周期中还剩下的时间片 在每一个调度周期的开始,priority 的值被赋给 counter, 然后每次该进程被调度执行时,counter 值都减少 当 counter 值为零时, 该进程用完自己在本调度周期中的时间片, 不再参与本调度周期的进程调度 当所有进程的时间片都用完时, 一个调度周期结束, 这样周而复始 另外, 可以看出 Linux 系统中的调度周期不是静态的, 它是一个动态变化的量, 例如, 处于可运行状态的进程的多少和它们 priority 的值都可以影响一个 epoch 的长短 在 2.4 以上的内核中,priority 被 nice 所取代, 但二者作用类似 在 SCHED_FIFO 调度策略中, 不同的进程根据静态优先级进行排队 ; 然后在同一优先级的队列中, 谁先准备好运行就先调度谁, 并且正在运行的进程不会被终止, 直到以下情况发生 : 被更高优先级的进程强占 CPU 自己因为资源请求而阻塞 自己主动放弃 CPU( 调用 sched_yield) SCHED_RR 与上面的 SCHED_FIFO 类似, 不同之处在于它给每个进程分配一个时间片, 时间片到了正在执行的进程就放弃执行 ; 时间片的长度可以通过 sched_rr_get_interval 调用得到

21 Linux 是一种非实时操作系统, 在某些对实时性要求比较严格的嵌入式应用中,Linux 系统的实时性一直是最大的顽症 不过, 也有人陆续推出 Linux 内核的实时补丁, 在一定程度上解决了实时性的问题 其中, 最有名的是 RT-Linux RT-Linux 是新墨西哥科技大学的研究成果, 它的基本思想是, 为了在 Linux 系统中提供对于硬实时的支持, 实现了一个微内核的小的实时操作系统, 而将普通 Linux 系统作为一个该操作系统中的一个低优先级的任务来运行 另外, 普通 Linux 系统中的任务可以通过 FIFO 和实时任务进行通信 RT-Linux 的框架如图 5.7 所示 Linux 应用程序 系统调用 FIFO Linux 内核实时任务 A 实时任务 B 实时任务 N RT-Linux 实时内核 硬件层 5.7 RT-Linux RT-Linux 的关键技术是通过软件来模拟硬件的中断控制器 当 Linux 系统要封锁 CPU 的中断时, RT-Linux 中的实时子系统会截取到这个请求, 把它记录下来, 而实际上并不真正封锁硬件中断, 这样就避免了由于封锁中断所造成的系统在一段时间没有响应的情况, 从而提高了实时性 当有硬件中断到来时, RT-Linux 截取该中断, 并判断是否有实时子系统中的中断例程来处理, 还是传递给普通的 Linux 内核进行处理 另外, 普通 Linux 系统中的最小定时精度由系统中的实时时钟的频率决定, 一般 Linux 系统将该时钟设置为每秒 100 个时钟中断, 所以 Linux 系统中一般的定时精度为 10ms, 即时钟周期是 10ms, 而 RT-Linux 通过将系统的实时时钟设置为单次触发状态, 可以提供十几个微秒级的调度粒度 RED-Linux 是另外一种实时 Linux 系统, 由加州大学 Irvine 分校开发 它将对实时调度的支持和 Linux 很好地实现在同一个操作系统内核中 它同时支持 3 种类型的调度算法, 即 :Time-Driven Priority-Driven Share-Driven RED-Linux 的设计目标就是提供一个可以支持各种调度算法的通用调度框架, 该系统给每个任务增加了如下几项属性, 并将它们作为进程调度的依据 Priority: 作业的优先级 Start-Time: 作业的开始时间 Finish-Time: 作业的结束时间 Budget: 作业在运行期间所要使用的资源数量 通过调整这些属性的取值及调度程序按照什么样的优先顺序来使用这些属性值, 几乎可以实现所有的调度算法 这样, 可以将 3 种不同的调度算法无缝 统一地结合到一起 RED-Linux 调度程序的框架结构如图 5.8 所示

22 5.8 RED-Linux 1. 和进程管理相关的内核文件都有哪些? 2. 什么是进程和线程? 3. 什么是进程描述符? 怎样得到当前进程的进程描述符? 4. 进程的内核栈有多大? 5. 进程的状态都有哪些? 在什么情况下发生转化? 6.Linux 中所有进程之间的关系是怎么样的? 联系方式 集团官网 : 嵌入式学院 : 移动互联网学院 : 企业学院 : 物联网学院 : 研发中心 :dev.hqyj.com 集团总部地址 : 北京市海淀区西三旗悦秀路北京明园大学校内华清远见教育集团 北京地址 : 北京市海淀区西三旗悦秀路北京明园大学校区, 电话 : /5 上海地址 : 上海市徐汇区漕溪路银海大厦 A 座 8 层, 电话 : 深圳地址 : 深圳市龙华新区人民北路美丽 AAA 大厦 15 层, 电话 : 成都地址 : 成都市武侯区科华北路 99 号科华大厦 6 层, 电话 : 南京地址 : 南京市白下区汉中路 185 号鸿运大厦 10 层, 电话 : 武汉地址 : 武汉市工程大学卓刀泉校区科技孵化器大楼 8 层, 电话 : 西安地址 : 西安市高新区高新一路 12 号创业大厦 D3 楼 5 层, 电话 :

Kernel Kernel Kernel Kernel load estimator runqueue kernel/sched.

Kernel Kernel Kernel Kernel load estimator runqueue kernel/sched. Linux Kernel 2.6 20321131 Kernel 2.4...3 Kernel 2.4...3 Kernel 2.4...3 Kernel 2.6...3...3 1....3 2....4 3. load estimator...4 4....4 5....4...4 1....4 2. runqueue kernel/sched.c...4 3. task_struct(include/linux/sched.h)...6...9

More information

中文模板

中文模板 操作系统课程作业 源码阅读报告 1 源码阅读报告 1. Linux 内核中进程管理模块的整体结构 Linux 内核的进程管理模块包括进程的数据结构表示 进程的创建与终止 进程调度 进程间通信 CPU 调度 进程同步 死锁处理等 整个进程管理模块以结构体 task_struct 为核心, 其他的操作都针对这个结构体及其各个成员进行操作 比如, 创建一个进程就是新建一个 task_struct 结构体,

More information

提纲 1 2 OS Examples for 3

提纲 1 2 OS Examples for 3 第 4 章 Threads2( 线程 2) 中国科学技术大学计算机学院 October 28, 2009 提纲 1 2 OS Examples for 3 Outline 1 2 OS Examples for 3 Windows XP Threads I An Windows XP application runs as a seperate process, and each process may

More information

<4D F736F F F696E74202D20B2D9D7F7CFB5CDB35F4C696E7578BDF8B3CCD3EBCFDFB3CC2E BBCE6C8DDC4A3CABD5D>

<4D F736F F F696E74202D20B2D9D7F7CFB5CDB35F4C696E7578BDF8B3CCD3EBCFDFB3CC2E BBCE6C8DDC4A3CABD5D> Linux 中的进程与线程 进程调度 Linux 线程 目录 1 进程控制块 (PCB) 是什么? PCB 的内容 Linux 下的 PCB 有什么特点? Task_struct 进程是程序执行时的一个实例 1. 有一段程序供其执行 2. 有起码的 私有财产, 也就是进程的专有的系统堆栈空间 3. 有 户口, 就是内核中的一个 task_struct 数据结构, 有了这个数据结构, 进程才能成为内核调度的一个基本单位,

More information

Microsoft PowerPoint - os_4.ppt

Microsoft PowerPoint - os_4.ppt 行 程 資 科 系 林 偉 川 行 程 概 念 行 程 與 程 式 主 要 的 不 同 點 : 程 式 是 被 放 在 外 部 的 儲 存 裝 置 如 磁 碟 上, 而 行 程 則 被 放 在 記 憶 體 中 程 式 在 儲 存 裝 置 中 是 靜 態 的, 而 行 程 在 記 憶 體 中 是 動 態 的, 它 會 隨 著 一 些 事 件 的 發 生 而 產 生 相 對 的 改 變 行 程, 就 是

More information

C/C++ - 文件IO

C/C++ - 文件IO C/C++ IO Table of contents 1. 2. 3. 4. 1 C ASCII ASCII ASCII 2 10000 00100111 00010000 31H, 30H, 30H, 30H, 30H 1, 0, 0, 0, 0 ASCII 3 4 5 UNIX ANSI C 5 FILE FILE 6 stdio.h typedef struct { int level ;

More information

Linux 操作系统分析 Chapter 9-2 Linux 中程序的执行 陈香兰 苏州研究院中国科学技术大学 Fall 2014 November 4,

Linux 操作系统分析 Chapter 9-2 Linux 中程序的执行 陈香兰  苏州研究院中国科学技术大学 Fall 2014 November 4, Linux 操作系统分析 Chapter 9-2 Linux 中程序的执行 陈香兰 (xlanchen@ustceducn) 计算机应用教研室 @ 计算机学院嵌入式系统实验室 @ 苏州研究院中国科学技术大学 Fall 2014 November 4, 2014 陈香兰 (xlanchen@ustceducn) ( 计算机应用教研室 Linux 操作系统分析 @ 计算机学院嵌入式系统实验室 Chapter

More information

ebook15-10

ebook15-10 1 0 10.1 U N I X V 7 4. 3 B S D S V R 3 P O S I X. 1 100 % 10.2 S I G S I G A B RT a b o r t S I G A L R M a l a r m V 7 1 5 S V R 4 4. 3 + B S D 31 < s i g n a l. h > 0 10. 9 k i l l 0 P O S I X. 1 D

More information

Microsoft Word - LJM05.doc

Microsoft Word - LJM05.doc 第 5 章 进程调度与负载均衡 调度工作涉及选择哪个 ( 哪些 ) 任务在哪个 ( 哪些 ) 处理器上运行, 解决各个进程公平地享用 CPU 资源的问题 具体需要确定当前进程可以占用 CPU 核多久 哪个进程将是下一个要运行的进程 负载均衡主要解决的是各个 CPU 忙闲不一的问题, 提高系统的整体吞吐率 调度和负载均衡大体上是与硬件架构无关的, 但是调度相关的进程切换则是体系结构紧密相关的内容 (

More information

第一章 概论

第一章  概论 1 2 3 4 5 6 7 8 Linux 7.1 7.1.1 1 1 2 3 2 3 1 2 3 3 1 2 3 7.1.2 1 2 1 2 3 4 5 7.1.3 1 1 2 3 2 7.1 3 7.1.4 1 1 PCB 2 3 2 PCB PCB PCB PCB PCB 4 1 2 PSW 3 CPU CPU 4 PCB PCB CPU PCB PCB PCB PCB PCB PCB PCB

More information

Windows RTEMS 1 Danilliu MMI TCP/IP QEMU i386 QEMU ARM POWERPC i386 IPC PC104 uc/os-ii uc/os MMI TCP/IP i386 PORT Linux ecos Linux ecos ecos eco

Windows RTEMS 1 Danilliu MMI TCP/IP QEMU i386 QEMU ARM POWERPC i386 IPC PC104 uc/os-ii uc/os MMI TCP/IP i386 PORT Linux ecos Linux ecos ecos eco Windows RTEMS 1 Danilliu MMI TCP/IP 80486 QEMU i386 QEMU ARM POWERPC i386 IPC PC104 uc/os-ii uc/os MMI TCP/IP i386 PORT Linux ecos Linux ecos ecos ecos Email www.rtems.com RTEMS ecos RTEMS RTEMS Windows

More information

ebook

ebook 3 3 3.1 3.1.1 ( ) 90 3 1966 B e r n s t e i n P ( i ) R ( i ) W ( i P ( i P ( j ) 1) R( i) W( j)=φ 2) W( i) R( j)=φ 3) W( i) W( j)=φ 3.1.2 ( p r o c e s s ) 91 Wi n d o w s Process Control Bl o c k P C

More information

1

1 1 2 3 4 5 GNUDebugger 6 7 void main(int argc, char **argv){ vulncpy(argv[1]); return; } void vulncpy(char *a){ char buf[30]; strcpy(buf, a); return; } *argv[1] buf Shellcode *argv[1]... &buf &buf 8 strcpy

More information

lec02.key

lec02.key 第 2 讲进程控制 张雷雷 zhangl@nju.edu.cn 南京 大学计算机科学与技术系 1 主要内容 用户 / 程序员眼中的进程 基本概念 ps 命令 进程创建, 等待, 终 止 ; 程序执 行行 Linux 内核眼中的进程 Linux 进程描述 Linux 内核通 用链表 Linux 进程 / 线程的实现机制 系统调 用!2 进程及线程基本定义 进程 (process) 处于执 行行期的程序及其所包含资源的总称

More information

前 言 首 先, 感 謝 你 購 買 了 Linux LPIC Level I + Novell CLA 11 這 本 書, 這 本 書 是 全 球 第 一 本 以 Novell SUSE Linux Enterprise Server 來 分 析 兩 大 Linux 認 證 的 自 學 手 冊 目 前 訪 間 充 斥 著 許 多 Linux 作 業 系 統 的 教 學 手 冊 考 照 的 書 籍,

More information

A Preliminary Implementation of Linux Kernel Virus and Process Hiding

A Preliminary Implementation of Linux Kernel Virus and Process Hiding 邵 俊 儒 翁 健 吉 妍 年 月 日 学 号 学 号 学 号 摘 要 结 合 课 堂 知 识 我 们 设 计 了 一 个 内 核 病 毒 该 病 毒 同 时 具 有 木 马 的 自 动 性 的 隐 蔽 性 和 蠕 虫 的 感 染 能 力 该 病 毒 获 得 权 限 后 会 自 动 将 自 身 加 入 内 核 模 块 中 劫 持 的 系 统 调 用 并 通 过 简 单 的 方 法 实 现 自 身 的

More information

C 1

C 1 C homepage: xpzhangme 2018 5 30 C 1 C min(x, y) double C // min c # include # include double min ( double x, double y); int main ( int argc, char * argv []) { double x, y; if( argc!=

More information

06721 main() lock pick proc() restart() [2][4] MINIX minix2.0 GDT, IDT irq table[] CPU CPU CPU CPU (IDTR) idt[] CPU _hwint00:! Interrupt

06721 main() lock pick proc() restart() [2][4] MINIX minix2.0 GDT, IDT irq table[] CPU CPU CPU CPU (IDTR) idt[] CPU _hwint00:! Interrupt MINIX ( 730000) ( 730000) MINIX MINIX2.0 MINIX : MINIX TP3 1 MINIX UNIX Tanenbaum UNIX MINIX LINUX MINIX MINIX MINIX1.0 UNIX V7 MINIX2.0[3] POSIX MINIX3 MINIX Gabriel A. Wainer 1994-1995 [5] 1998 I/O 2002

More information

华恒家庭网关方案

华恒家庭网关方案 LINUX V1.5 1 2 1 2 LINUX WINDOWS PC VC LINUX WINDOWS LINUX 90% GUI LINUX C 3 REDHAT 9 LINUX PC TFTP/NFS http://www.hhcn.com/chinese/embedlinux-res.html minicom NFS mount C HHARM9-EDU 1 LINUX HHARM9-EDU

More information

泛型编程与C++标准库

泛型编程与C++标准库 28 第 2 章进程管理和调度 第 2 章 进程管理和调度 所 有的现代操作系统都能够同时运行若干进程, 至少用户错觉上是这样 如果系统只有一个处理器, 那么在给定时刻只有一个程序可以运行 在多处理器系统中, 可以真正并行运行的进程数目, 取决于物理 CPU 的数目 内核和处理器建立了多任务的错觉, 即可以并行做几种操作, 这是通过以很短的间隔在系统运行的应用程序之间不停切换而做到的 由于切换间隔如此之短,

More information

エスポラージュ株式会社 住所 : 東京都江東区大島 東急ドエルアルス大島 HP: ******************* * 关于 Java 测试试题 ******

エスポラージュ株式会社 住所 : 東京都江東区大島 東急ドエルアルス大島 HP:  ******************* * 关于 Java 测试试题 ****** ******************* * 关于 Java 测试试题 ******************* 問 1 运行下面的程序, 选出一个正确的运行结果 public class Sample { public static void main(string[] args) { int[] test = { 1, 2, 3, 4, 5 ; for(int i = 1 ; i System.out.print(test[i]);

More information

新版 明解C++入門編

新版 明解C++入門編 511!... 43, 85!=... 42 "... 118 " "... 337 " "... 8, 290 #... 71 #... 413 #define... 128, 236, 413 #endif... 412 #ifndef... 412 #if... 412 #include... 6, 337 #undef... 413 %... 23, 27 %=... 97 &... 243,

More information

C PICC C++ C++ C C #include<pic.h> C static volatile unsigned char 0x01; static volatile unsigned char 0x02; static volatile unsigned cha

C PICC C++ C++ C C #include<pic.h> C static volatile unsigned char 0x01; static volatile unsigned char 0x02; static volatile unsigned cha CYPOK CYPOK 1 UltraEdit Project-->Install Language Tool: Language Suite----->hi-tech picc Tool Name ---->PICC Compiler Executable ---->c:hi-picinpicc.exe ( Command-line Project-->New Project-->File Name--->myc

More information

2 2 3 DLight CPU I/O DLight Oracle Solaris (DTrace) C/C++ Solaris DLight DTrace DLight DLight DLight C C++ Fortran CPU I/O DLight AM

2 2 3 DLight CPU I/O DLight Oracle Solaris (DTrace) C/C++ Solaris DLight DTrace DLight DLight DLight C C++ Fortran CPU I/O DLight AM Oracle Solaris Studio 12.2 DLight 2010 9 2 2 3 DLight 3 3 6 13 CPU 16 18 21 I/O DLight Oracle Solaris (DTrace) C/C++ Solaris DLight DTrace DLight DLight DLight C C++ Fortran CPU I/O DLight AMP Apache MySQL

More information

How to Debug Tuxedo Server printf( Input data is: %s, inputstr); fprintf(stdout, Input data is %s, inputstr); fprintf(stderr, Input data is %s, inputstr); printf( Return data is: %s, outputstr); tpreturn(tpsuccess,

More information

, 7, Windows,,,, : ,,,, ;,, ( CIP) /,,. : ;, ( 21 ) ISBN : -. TP CIP ( 2005) 1

, 7, Windows,,,, : ,,,, ;,, ( CIP) /,,. : ;, ( 21 ) ISBN : -. TP CIP ( 2005) 1 21 , 7, Windows,,,, : 010-62782989 13501256678 13801310933,,,, ;,, ( CIP) /,,. : ;, 2005. 11 ( 21 ) ISBN 7-81082 - 634-4... - : -. TP316-44 CIP ( 2005) 123583 : : : : 100084 : 010-62776969 : 100044 : 010-51686414

More information

Chapter 9: Objects and Classes

Chapter 9: Objects and Classes Java application Java main applet Web applet Runnable Thread CPU Thread 1 Thread 2 Thread 3 CUP Thread 1 Thread 2 Thread 3 ,,. (new) Thread (runnable) start( ) CPU (running) run ( ) blocked CPU sleep(

More information

Bus Hound 5

Bus Hound 5 Bus Hound 5.0 ( 1.0) 21IC 2007 7 BusHound perisoft PC hound Bus Hound 6.0 5.0 5.0 Bus Hound, IDE SCSI USB 1394 DVD Windows9X,WindowsMe,NT4.0,2000,2003,XP XP IRP Html ZIP SCSI sense USB Bus Hound 1 Bus

More information

<4D F736F F D20B5DA32D5C220416E64726F6964BFAAB7A2BBB7BEB3B4EEBDA82E646F6378>

<4D F736F F D20B5DA32D5C220416E64726F6964BFAAB7A2BBB7BEB3B4EEBDA82E646F6378> Android 应用程序开发与典型案例 作者 : 华清远见 第 2 章 Android 开发环境搭建 本章简介 本章主要介绍在 Windows 环境下,Android 开发环境的搭建步骤及注意事项, 包括 JDK 和 Java 开发环境的安装和配置 Eclipse 的安装 Android SDK 和 ADT 的安装和配置等 ; 同时介绍了 Android 开发的基本步骤 2.1 Android 开发环境的安装与配置

More information

1 CPU interrupt INT trap CPU exception

1 CPU interrupt INT trap CPU exception 1 CPU interrupt INT trap CPU exception 2 X86 CPU gate 64 16 1 2 5 8 16 16 P DPL 00101 TSS 101 DPL P 1 64 16 1 2 1 1 3 3 5 16 16 16 P DPL 0 D 000 16 110 111 100 D 1=32 0=16 DPL P 1 INT DPL1>=CPL>=DPL CPU

More information

新版 明解C言語入門編

新版 明解C言語入門編 328, 4, 110, 189, 103, 11... 318. 274 6 ; 10 ; 5? 48 & & 228! 61!= 42 ^= 66 _ 82 /= 66 /* 3 / 19 ~ 164 OR 53 OR 164 = 66 ( ) 115 ( ) 31 ^ OR 164 [] 89, 241 [] 324 + + 4, 19, 241 + + 22 ++ 67 ++ 73 += 66

More information

Guava学习之Resources

Guava学习之Resources Resources 提供提供操作 classpath 路径下所有资源的方法 除非另有说明, 否则类中所有方法的参数都不能为 null 虽然有些方法的参数是 URL 类型的, 但是这些方法实现通常不是以 HTTP 完成的 ; 同时这些资源也非 classpath 路径下的 下面两个函数都是根据资源的名称得到其绝对路径, 从函数里面可以看出,Resources 类中的 getresource 函数都是基于

More information

Linux kernel exploit研究和探索

Linux kernel exploit研究和探索 Linux kernel exploit DOC alert7 PPT e4gle 2002-12-2 1 2002-12-2 2 Linux kernel exploit kernel exploit exploit exploit exploit (Kernel Buffer Overflow) (Kernel

More information

PowerPoint 演示文稿

PowerPoint 演示文稿 The BitCoin Scripting Language 交易实例 交易结构 "result": { "txid": "921a dd24", "hash": "921a dd24", "version": 1, "size": 226, "locktime": 0, "vin": [ ], "vout": [ ], "blockhash": "0000000000000000002c510d

More information

C/C++ - 字符输入输出和字符确认

C/C++ - 字符输入输出和字符确认 C/C++ Table of contents 1. 2. getchar() putchar() 3. (Buffer) 4. 5. 6. 7. 8. 1 2 3 1 // pseudo code 2 read a character 3 while there is more input 4 increment character count 5 if a line has been read,

More information

int *p int a 0x00C7 0x00C7 0x00C int I[2], *pi = &I[0]; pi++; char C[2], *pc = &C[0]; pc++; float F[2], *pf = &F[0]; pf++;

int *p int a 0x00C7 0x00C7 0x00C int I[2], *pi = &I[0]; pi++; char C[2], *pc = &C[0]; pc++; float F[2], *pf = &F[0]; pf++; Memory & Pointer trio@seu.edu.cn 2.1 2.1.1 1 int *p int a 0x00C7 0x00C7 0x00C7 2.1.2 2 int I[2], *pi = &I[0]; pi++; char C[2], *pc = &C[0]; pc++; float F[2], *pf = &F[0]; pf++; 2.1.3 1. 2. 3. 3 int A,

More information

程序 linux/include/linux/math_emu.h 1 /* 2 * linux/include/linux/math_emu.h 3 * 4 * (C) 1991 Linus Torvalds 5 */ 6 #ifndef _LINUX_MATH_EMU_H 7 #de

程序 linux/include/linux/math_emu.h 1 /* 2 * linux/include/linux/math_emu.h 3 * 4 * (C) 1991 Linus Torvalds 5 */ 6 #ifndef _LINUX_MATH_EMU_H 7 #de 程序 14-24 linux/include/linux/math_emu.h 1 /* 2 * linux/include/linux/math_emu.h 3 * 4 * (C) 1991 Linus Torvalds 5 */ 6 #ifndef _LINUX_MATH_EMU_H 7 #define _LINUX_MATH_EMU_H 8 9 #include

More information

CC213

CC213 : (Ken-Yi Lee), E-mail: feis.tw@gmail.com 49 [P.51] C/C++ [P.52] [P.53] [P.55] (int) [P.57] (float/double) [P.58] printf scanf [P.59] [P.61] ( / ) [P.62] (char) [P.65] : +-*/% [P.67] : = [P.68] : ,

More information

C/C++ - 函数

C/C++ - 函数 C/C++ Table of contents 1. 2. 3. & 4. 5. 1 2 3 # include # define SIZE 50 int main ( void ) { float list [ SIZE ]; readlist (list, SIZE ); sort (list, SIZE ); average (list, SIZE ); bargragh

More information

正文.indd

正文.indd 第 3 章 进程管理 本章引入进程的概念 进程是 Unix 操作系统抽象概念中最基本的一种 其中涉及进程的定 义以及相关的概念 比如线程 然后讨论 Linux 内核如何管理每个进程 它们在内核中如何被列 举 如何创建 最终又如何消亡 我们拥有操作系统就是为了运行用户程序 因此 进程管理就 是所有操作系统的心脏所在 Linux 也不例外 3.1 进程 进程就是处于执行期的程序 目标码存放在某种存储介质上

More information

static struct file_operations gpio_ctl_fops={ ioctl: gpio_ctl_ioctl, open : gpio_open, release: gpio_release, ; #defineled1_on() (GPBDAT &= ~0x1) #def

static struct file_operations gpio_ctl_fops={ ioctl: gpio_ctl_ioctl, open : gpio_open, release: gpio_release, ; #defineled1_on() (GPBDAT &= ~0x1) #def Kaise s 2410 Board setting [1]. Device Driver Device Driver Linux s Kernel ARM s kernel s3c2410_kernel2.4.18_r1.1_change.tar.bz2 /usr/src (1) #cd /usr/src (2) #tar xfj s3c2410_kernel2.4.18_r1.1_change.tar.bz2

More information

untitled

untitled Work Managers 什 Work Managers? WebLogic Server 9.x 行 (thread) 理 thread pool 數量 立 execute queues 來 量 理 thread count, thread priority 參數 理 thread pool 數量? WebLogic Server 9.x 理 行 (thread) (self-tuning) 句

More information

Agilent N5700 N5741A-49A, N5750A-52A, N5761A-69A, N5770A-72A W 1500 W 600 V 180 A 1 U Vac AC LAN,USB GPIB Agilent N5700 1U 750W 1500W 24

Agilent N5700 N5741A-49A, N5750A-52A, N5761A-69A, N5770A-72A W 1500 W 600 V 180 A 1 U Vac AC LAN,USB GPIB Agilent N5700 1U 750W 1500W 24 Agilent N700 N71A-9A, N70A-2A, N761A-69A, N770A-72A 2 70 W 100 W 600 V 180 A 1 U 8-26 Vac AC LAN,USB GPIB Agilent N700 1U 70W 100W 2 6V 600V 1.A 180A N700 1U 19 100W LED N700 OVP UVL UVL OVP N700 GPIB

More information

FY.DOC

FY.DOC 高 职 高 专 21 世 纪 规 划 教 材 C++ 程 序 设 计 邓 振 杰 主 编 贾 振 华 孟 庆 敏 副 主 编 人 民 邮 电 出 版 社 内 容 提 要 本 书 系 统 地 介 绍 C++ 语 言 的 基 本 概 念 基 本 语 法 和 编 程 方 法, 深 入 浅 出 地 讲 述 C++ 语 言 面 向 对 象 的 重 要 特 征 : 类 和 对 象 抽 象 封 装 继 承 等 主

More information

untitled

untitled 3 C++ 3.1 3.2 3.3 3.4 new delete 3.5 this 3.6 3.7 3.1 3.1 class struct union struct union C class C++ C++ 3.1 3.1 #include struct STRING { typedef char *CHARPTR; // CHARPTR s; // int strlen(

More information

新・解きながら学ぶC言語

新・解きながら学ぶC言語 330!... 67!=... 42 "... 215 " "... 6, 77, 222 #define... 114, 194 #include... 145 %... 21 %... 21 %%... 21 %f... 26 %ld... 162 %lf... 26 %lu... 162 %o... 180 %p... 248 %s... 223, 224 %u... 162 %x... 180

More information

SDK 概要 使用 Maven 的用户可以从 Maven 库中搜索 "odps-sdk" 获取不同版本的 Java SDK: 包名 odps-sdk-core odps-sdk-commons odps-sdk-udf odps-sdk-mapred odps-sdk-graph 描述 ODPS 基

SDK 概要 使用 Maven 的用户可以从 Maven 库中搜索 odps-sdk 获取不同版本的 Java SDK: 包名 odps-sdk-core odps-sdk-commons odps-sdk-udf odps-sdk-mapred odps-sdk-graph 描述 ODPS 基 开放数据处理服务 ODPS SDK SDK 概要 使用 Maven 的用户可以从 Maven 库中搜索 "odps-sdk" 获取不同版本的 Java SDK: 包名 odps-sdk-core odps-sdk-commons odps-sdk-udf odps-sdk-mapred odps-sdk-graph 描述 ODPS 基础功能的主体接口, 搜索关键词 "odpssdk-core" 一些

More information

幻灯片 1

幻灯片 1 操作系统课程实验 Lab1:bootloader 启动 ucore os 大纲 x86 启动顺序 C 函数调用 gcc 内联汇编 (inline assembly) x86-32 下的中断处理 理解 x86-32 平台的启动过程理解 x86-32 的实模式 保护模式理解段机制 x86 启动顺序 x86 启动顺序 寄存器初始值 摘自 "IA-32 Intel 体系结构软件开发者手册 " x86 启动顺序

More information

C++ 程序设计 告别 OJ1 - 参考答案 MASTER 2019 年 5 月 3 日 1

C++ 程序设计 告别 OJ1 - 参考答案 MASTER 2019 年 5 月 3 日 1 C++ 程序设计 告别 OJ1 - 参考答案 MASTER 2019 年 月 3 日 1 1 INPUTOUTPUT 1 InputOutput 题目描述 用 cin 输入你的姓名 ( 没有空格 ) 和年龄 ( 整数 ), 并用 cout 输出 输入输出符合以下范例 输入 master 999 输出 I am master, 999 years old. 注意 "," 后面有一个空格,"." 结束,

More information

OOP with Java 通知 Project 4: 4 月 18 日晚 9 点 关于抄袭 没有分数

OOP with Java 通知 Project 4: 4 月 18 日晚 9 点 关于抄袭 没有分数 OOP with Java Yuanbin Wu cs@ecnu OOP with Java 通知 Project 4: 4 月 18 日晚 9 点 关于抄袭 没有分数 复习 类的复用 组合 (composition): has-a 关系 class MyType { public int i; public double d; public char c; public void set(double

More information

目 录

目 录 1 Quick51...1 1.1 SmartSOPC Quick51...1 1.2 Quick51...1 1.3 Quick51...2 2 Keil C51 Quick51...4 2.1 Keil C51...4 2.2 Keil C51...4 2.3 1 Keil C51...4 2.4 Flash Magic...9 2.5 ISP...9 2.6...10 2.7 Keil C51...12

More information

To remove this message please register. 学习资料 4. 进程从绻统踃用返回到用户态时 ; 5. 内核处理完中断后, 进程返回到用户态 ; 六 : 进程队列 :( 对队列都有初始化 添加 删除等功能 ) 1: 运行队列 :Linux 绻统为处于帱绪态的进程的队列

To remove this message please register. 学习资料 4. 进程从绻统踃用返回到用户态时 ; 5. 内核处理完中断后, 进程返回到用户态 ; 六 : 进程队列 :( 对队列都有初始化 添加 删除等功能 ) 1: 运行队列 :Linux 绻统为处于帱绪态的进程的队列 To remove this message please register. 学习资料 Linux 进程与踃度学习 ----------------------------------------------------------------------------------------------- +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

More information

新・明解C言語入門編『索引』

新・明解C言語入門編『索引』 !... 75!=... 48 "... 234 " "... 9, 84, 240 #define... 118, 213 #include... 148 %... 23 %... 23, 24 %%... 23 %d... 4 %f... 29 %ld... 177 %lf... 31 %lu... 177 %o... 196 %p... 262 %s... 242, 244 %u... 177

More information

Converting image (bmp/jpg) file into binary format

Converting image (bmp/jpg) file into binary format RAiO Image Tool 操作说明 Version 1.0 July 26, 2016 RAiO Technology Inc. Copyright RAiO Technology Inc. 2013 RAiO TECHNOLOGY INC. www.raio.com.tw Revise History Version Date Description 0.1 September 01, 2014

More information

untitled

untitled A, 3+A printf( ABCDEF ) 3+ printf( ABCDEF ) 2.1 C++ main main main) * ( ) ( ) [ ].* ->* ()[] [][] ** *& char (f)(int); ( ) (f) (f) f (int) f int char f char f(int) (f) char (*f)(int); (*f) (int) (

More information

手册 doc

手册 doc 1. 2. 3. 3.1 3.2 3.3 SD 3.4 3.5 SD 3.6 3.7 4. 4.1 4.2 4.3 SD 4.4 5. 5.1 5.2 5.3 SD 6. 1. 1~3 ( ) 320x240~704x288 66 (2G SD 320x2401FPS ) 32M~2G SD SD SD SD 24V DC 3W( ) -10~70 10~90% 154x44x144mm 2. DVR106

More information

epub83-1

epub83-1 C++Builder 1 C + + B u i l d e r C + + B u i l d e r C + + B u i l d e r C + + B u i l d e r 1.1 1.1.1 1-1 1. 1-1 1 2. 1-1 2 A c c e s s P a r a d o x Visual FoxPro 3. / C / S 2 C + + B u i l d e r / C

More information

ebook15-C

ebook15-C C 1 1.1 l s ( 1 ) - i i 4. 14 - d $ l s -ldi /etc/. /etc/.. - i i 3077 drwxr-sr-x 7 bin 2048 Aug 5 20:12 /etc/./ 2 drwxr-xr-x 13 root 512 Aug 5 20:11 /etc/../ $ls -ldi /. /..... i 2 2 drwxr-xr-x 13 root

More information

六域链联盟 SDChain-Matrix 节点搭建指南 2018/07/26 Version : 1.0.0

六域链联盟 SDChain-Matrix 节点搭建指南 2018/07/26 Version : 1.0.0 SDChain-Matrix 节点搭建指南 目录 1 环境要求... 3 2 软件下载... 4 3 安装部署... 4 3.1 部署可执行程序目录... 4 3.2 部署配置文件目录... 4 3.3 部署数据库文件目录... 4 3.4 部署日志文件目录... 4 3.5 部署依赖库文件目录... 4 4 配置参数... 5 5 启动运行... 7 5.1 普通模式启动... 7 5.2 加载启动模式...

More information

ROP_bamboofox.key

ROP_bamboofox.key ROP Return Oriented Programming Lays @ BambooFox Who Am I Lays / L4ys / 累死 - l4ys.tw Reverse Engineering BambooFox / HITCON Outline Buffer Overflow ret2libc / ret2text Return Oriented Programming Payload

More information

ebook15-4

ebook15-4 4 4.1 I / O I / s t a t s t a t ( ) U N I X 4.2 stat fstat lstat s t a t #include #include int stat(const char p a * t h n a m e, struct stat b * u f) ; int fstat(int f i l e

More information

C/C++ - 字符串与字符串函数

C/C++ - 字符串与字符串函数 C/C++ Table of contents 1. 2. 3. 4. 1 char C 2 char greeting [50] = " How " " are " " you?"; char greeting [50] = " How are you?"; 3 printf ("\" Ready, go!\" exclaimed John."); " Ready, go!" exclaimed

More information

Fun Time (1) What happens in memory? 1 i n t i ; 2 s h o r t j ; 3 double k ; 4 char c = a ; 5 i = 3; j = 2; 6 k = i j ; H.-T. Lin (NTU CSIE) Referenc

Fun Time (1) What happens in memory? 1 i n t i ; 2 s h o r t j ; 3 double k ; 4 char c = a ; 5 i = 3; j = 2; 6 k = i j ; H.-T. Lin (NTU CSIE) Referenc References (Section 5.2) Hsuan-Tien Lin Deptartment of CSIE, NTU OOP Class, March 15-16, 2010 H.-T. Lin (NTU CSIE) References OOP 03/15-16/2010 0 / 22 Fun Time (1) What happens in memory? 1 i n t i ; 2

More information

AIX系统培训7.ppt

AIX系统培训7.ppt AIX Undefined Defined Available No Differenc bound vmstat when %user + %sys greater than 80% I/O bound vmstat when %iowait greater than 40% (AIX 4.3.3 or later) lication

More information

c_cpp

c_cpp C C++ C C++ C++ (object oriented) C C++.cpp C C++ C C++ : for (int i=0;i

More information

untitled

untitled MPICH anzhulin@sohu.com 1 MPICH for Microsoft Windows 1.1 MPICH for Microsoft Windows Windows NT4/2000/XP Professional Server Windows 95/98 TCP/IP MPICH MS VC++ 6.x MS VC++.NET Compaq Visual Fortran 6.x

More information

AL-MX200 Series

AL-MX200 Series PostScript Level3 Compatible NPD4760-00 TC Seiko Epson Corporation Seiko Epson Corporation ( ) Seiko Epson Corporation Seiko Epson Corporation Epson Seiko Epson Corporation Apple Bonjour ColorSync Macintosh

More information

W. Richard Stevens UNIX Sockets API echo Sockets TCP OOB IO C struct C/C++ UNIX fork() select(2)/poll(2)/epoll(4) IO IO CPU 100% libevent UNIX CPU IO

W. Richard Stevens UNIX Sockets API echo Sockets TCP OOB IO C struct C/C++ UNIX fork() select(2)/poll(2)/epoll(4) IO IO CPU 100% libevent UNIX CPU IO Linux muduo C++ (giantchen@gmail.com) 2012-09-30 C++ TCP C++ x86-64 Linux TCP one loop per thread Linux native muduo C++ IT 5 C++ muduo 2 C++ C++ Primer 4 W. Richard Stevens UNIX Sockets API echo Sockets

More information

chap07.key

chap07.key #include void two(); void three(); int main() printf("i'm in main.\n"); two(); return 0; void two() printf("i'm in two.\n"); three(); void three() printf("i'm in three.\n"); void, int 标识符逗号分隔,

More information

ebook 86-15

ebook 86-15 15 G t k + d e l e t e _ e v e n t G n o m e G n o m e 15.1 GnomeDialog G t k + G n o m e D i a l o g 15.1.1 G n o m e D i a l o g g n o m e _ d i a l o g _ n e w ( ) G N O M E _ D I A L O G ( d i a l

More information

EK-STM32F

EK-STM32F STMEVKIT-STM32F10xx8 软 件 开 发 入 门 指 南 目 录 1 EWARM 安 装... 1 1.1 第 一 步 : 在 线 注 册... 1 1.2 第 二 步 : 下 载 软 件... 2 1.3 第 三 步 : 安 装 EWARM... 3 2 基 于 STMEVKIT-STM32F10xx8 的 示 例 代 码 运 行... 6 2.1 GPIO Demo... 6 2.2

More information

多进程管理副本.key

多进程管理副本.key 美妙的多进程管理 造 个类 gunicorn 的轮 blog: xiaorui.cc github: github.com/rfyiamcool 内容 supervisor vs gunicorn vs uwsgi linux 异步信号 孤 进程 vs 僵 进程 daemon 的实现 prefork 是怎么 回事 打造 个较完善的多进程管理轮 怎么写代码 Master Worker elegance

More information

Microsoft Word - 把时间当作朋友(2011第3版)3.0.b.06.doc

Microsoft Word - 把时间当作朋友(2011第3版)3.0.b.06.doc 2 5 8 11 0 13 1. 13 2. 15 3. 18 1 23 1. 23 2. 26 3. 28 2 36 1. 36 2. 39 3. 42 4. 44 5. 49 6. 51 3 57 1. 57 2. 60 3. 64 4. 66 5. 70 6. 75 7. 83 8. 85 9. 88 10. 98 11. 103 12. 108 13. 112 4 115 1. 115 2.

More information

6 C51 ANSI C Turbo C C51 Turbo C C51 C51 C51 C51 C51 C51 C51 C51 C C C51 C51 ANSI C MCS-51 C51 ANSI C C C51 bit Byte bit sbit

6 C51 ANSI C Turbo C C51 Turbo C C51 C51 C51 C51 C51 C51 C51 C51 C C C51 C51 ANSI C MCS-51 C51 ANSI C C C51 bit Byte bit sbit 6 C51 ANSI C Turbo C C51 Turbo C C51 C51 C51 C51 C51 C51 C51 C51 C51 6.1 C51 6.1.1 C51 C51 ANSI C MCS-51 C51 ANSI C C51 6.1 6.1 C51 bit Byte bit sbit 1 0 1 unsigned char 8 1 0 255 Signed char 8 11 128

More information

untitled

untitled 1 DBF (READDBF.C)... 1 2 (filetest.c)...2 3 (mousetes.c)...3 4 (painttes.c)...5 5 (dirtest.c)...9 6 (list.c)...9 1 dbf (readdbf.c) /* dbf */ #include int rf,k,reclen,addr,*p1; long brec,erec,i,j,recnum,*p2;

More information

C C C The Most Beautiful Language and Most Dangerous Language in the Programming World! C 2 C C C 4 C 40 30 10 Project 30 C Project 3 60 Project 40

C C C The Most Beautiful Language and Most Dangerous Language in the Programming World! C 2 C C C 4 C 40 30 10 Project 30 C Project 3 60 Project 40 C C trio@seu.edu.cn C C C C The Most Beautiful Language and Most Dangerous Language in the Programming World! C 2 C C C 4 C 40 30 10 Project 30 C Project 3 60 Project 40 Week3 C Week5 Week5 Memory & Pointer

More information

Microsoft Word - 正文.doc

Microsoft Word - 正文.doc 1 2 1 2 3 4 5 6 7 8 9 10 3 1 150 2 150 1 1 1.1 1.1.1 1.2 1.2.1 1.2.2 1.2.3 1.3 1.3.1 1.3.2 1.4 1.4.1 CPU 1.4.2 I/O 1.4.3 I/O 1.5 1.5.1 CISC RISC 1.5.2 1.5.3 1.6 1.6.1 1.6.2 N 1.6.3 2 2.1 2.1.1 2.1.2 2.1.3

More information

无类继承.key

无类继承.key 无类继承 JavaScript 面向对象的根基 周爱 民 / aimingoo aiming@gmail.com https://aimingoo.github.io https://github.com/aimingoo rand = new Person("Rand McKinnon",... https://docs.oracle.com/cd/e19957-01/816-6408-10/object.htm#1193255

More information

ebook140-8

ebook140-8 8 Microsoft VPN Windows NT 4 V P N Windows 98 Client 7 Vintage Air V P N 7 Wi n d o w s NT V P N 7 VPN ( ) 7 Novell NetWare VPN 8.1 PPTP NT4 VPN Q 154091 M i c r o s o f t Windows NT RAS [ ] Windows NT4

More information

51 C 51 isp 10 C PCB C C C C KEIL

51 C 51 isp 10   C   PCB C C C C KEIL http://wwwispdowncom 51 C " + + " 51 AT89S51 In-System-Programming ISP 10 io 244 CPLD ATMEL PIC CPLD/FPGA ARM9 ISP http://wwwispdowncom/showoneproductasp?productid=15 51 C C C C C ispdown http://wwwispdowncom

More information

软件测试(TA07)第一学期考试

软件测试(TA07)第一学期考试 一 判 断 题 ( 每 题 1 分, 正 确 的, 错 误 的,20 道 ) 1. 软 件 测 试 按 照 测 试 过 程 分 类 为 黑 盒 白 盒 测 试 ( ) 2. 在 设 计 测 试 用 例 时, 应 包 括 合 理 的 输 入 条 件 和 不 合 理 的 输 入 条 件 ( ) 3. 集 成 测 试 计 划 在 需 求 分 析 阶 段 末 提 交 ( ) 4. 单 元 测 试 属 于 动

More information

untitled

untitled 1 Outline 數 料 數 數 列 亂數 練 數 數 數 來 數 數 來 數 料 利 料 來 數 A-Z a-z _ () 不 數 0-9 數 不 數 SCHOOL School school 數 讀 school_name schoolname 易 不 C# my name 7_eleven B&Q new C# (1) public protected private params override

More information

epub 33-8

epub 33-8 8 1) 2) 3) A S C I I 4 C I / O I / 8.1 8.1.1 1. ANSI C F I L E s t d i o. h typedef struct i n t _ f d ; i n t _ c l e f t ; i n t _ m o d e ; c h a r *_ n e x t ; char *_buff; /* /* /* /* /* 1 5 4 C FILE

More information

静态分析 投放文件 行为分析 互斥量 (Mutexes) 执行的命令 创建的服务 启动的服务 进程 cmd.exe PID: 2520, 上一级进程 PID: 2556 cmd.exe PID: 2604, 上一级进程 PID: 2520 访问的文件 C:\Users\test\AppData\Lo

静态分析 投放文件 行为分析 互斥量 (Mutexes) 执行的命令 创建的服务 启动的服务 进程 cmd.exe PID: 2520, 上一级进程 PID: 2556 cmd.exe PID: 2604, 上一级进程 PID: 2520 访问的文件 C:\Users\test\AppData\Lo 魔盾安全分析报告 分析类型 开始时间 结束时间 持续时间 分析引擎版本 FILE 2016-11-25 00:20:03 2016-11-25 00:22:18 135 秒 1.4-Maldun 虚拟机机器名 标签 虚拟机管理 开机时间 关机时间 win7-sp1-x64 win7-sp1-x64 KVM 2016-11-25 00:20:03 2016-11-25 00:22:18 魔盾分数 0.0

More information

1 LINUX IDE Emacs gcc gdb Emacs + gcc + gdb IDE Emacs IDE C Emacs Emacs IDE ICE Integrated Computing Environment Emacs Unix Linux Emacs Emacs Emacs Un

1 LINUX IDE Emacs gcc gdb Emacs + gcc + gdb IDE Emacs IDE C Emacs Emacs IDE ICE Integrated Computing Environment Emacs Unix Linux Emacs Emacs Emacs Un Linux C July 27, 2016 Contents 1 Linux IDE 1 2 GCC 3 2.1 hello.c hello.exe........................... 5 2.2............................... 9 2.2.1 -Wall................................ 9 2.2.2 -E..................................

More information

PIC_SERVER (11) SMTP ( ) ( ) PIC_SERVER (10) SMTP PIC_SERVER (event driven) PIC_SERVER SMTP 1. E-

PIC_SERVER (11) SMTP  ( ) ( ) PIC_SERVER (10) SMTP  PIC_SERVER (event driven)  PIC_SERVER SMTP  1.  E- (2005-02-01) (2005-04-28) PIC_SERVER (10) SMTP E-mail PIC_SERVER (event driven) E-mail PIC_SERVER SMTP E-mail 1. E-mail E-mail 1 (1) (2) (3) (4) 1 1. 2 E-mail A E-mail B E-mail SMTP(Simple Mail Transfer

More information

05_資源分享-NFS及NIS.doc

05_資源分享-NFS及NIS.doc 5 NFS NFS Server NFS Client NIS NIS 5-0 (Network File System, NFS) Unix NFS mount NFS... Network Information Service NIS Linux NIS NIS NIS / / /etc/passwd /etc/group NFS NIS 5-1 NFS 5-1-1 NFS NFS Network

More information

OOP with Java 通知 Project 4: 4 月 19 日晚 9 点

OOP with Java 通知 Project 4: 4 月 19 日晚 9 点 OOP with Java Yuanbin Wu cs@ecnu OOP with Java 通知 Project 4: 4 月 19 日晚 9 点 复习 类的复用 组合 (composition): has-a 关系 class MyType { public int i; public double d; public char c; public void set(double x) { d

More information

User ID 150 Password - User ID 150 Password Mon- Cam-- Invalid Terminal Mode No User Terminal Mode No User Mon- Cam-- 2

User ID 150 Password - User ID 150 Password Mon- Cam-- Invalid Terminal Mode No User Terminal Mode No User Mon- Cam-- 2 Terminal Mode No User User ID 150 Password - User ID 150 Password Mon- Cam-- Invalid Terminal Mode No User Terminal Mode No User Mon- Cam-- 2 Mon1 Cam-- Mon- Cam-- Prohibited M04 Mon1 Cam03 Mon1 Cam03

More information

第7章-并行计算.ppt

第7章-并行计算.ppt EFEP90 10CDMP3 CD t 0 t 0 To pull a bigger wagon, it is easier to add more oxen than to grow a gigantic ox 10t 0 t 0 n p Ts Tp if E(n, p) < 1 p, then T (n) < T (n, p) s p S(n,p) = p : f(x)=sin(cos(x))

More information

Microsoft Word - 11.doc

Microsoft Word - 11.doc 除 錯 技 巧 您 將 於 本 章 學 到 以 下 各 項 : 如 何 在 Visual C++ 2010 的 除 錯 工 具 控 制 下 執 行 程 式? 如 何 逐 步 地 執 行 程 式 的 敘 述? 如 何 監 看 或 改 變 程 式 中 的 變 數 值? 如 何 監 看 程 式 中 計 算 式 的 值? 何 謂 Call Stack? 何 謂 診 斷 器 (assertion)? 如 何

More information

ebook 132-6

ebook 132-6 6 SQL Server Windows NT Windows 2000 6.1 Enterprise Manager SQL Server Enterprise Manager( ) (Microsoft Management C o n s o l e M M C ) Enterprise Manager SQL Server Enterprise Manager 6.1.1 Enterprise

More information

36 p->p_osptr->p_ysptr = p->p_ysptr; 37 if (p->p_ysptr) 38 p->p_ysptr->p_osptr = p->p_osptr; 39 else 40 p->p_pptr->p_cptr = p->p_osptr; 41 free_page((

36 p->p_osptr->p_ysptr = p->p_ysptr; 37 if (p->p_ysptr) 38 p->p_ysptr->p_osptr = p->p_osptr; 39 else 40 p->p_pptr->p_cptr = p->p_osptr; 41 free_page(( 程序 8-7 linux/kernel/exit.c 1 2 * linux/kernel/exit.c 3 * 4 * (C) 1991 Linus Torvalds 5 6 7 #define DEBUG_PROC_TREE // 定义符号 调试进程树 8 9 #include // 错误号头文件 包含系统中各种出错号 (Linus 从 minix 中引进的 ) 10 #include

More information

Oracle 4

Oracle 4 Oracle 4 01 04 Oracle 07 Oracle Oracle Instance Oracle Instance Oracle Instance Oracle Database Oracle Database Instance Parameter File Pfile Instance Instance Instance Instance Oracle Instance System

More information

_汪_文前新ok[3.1].doc

_汪_文前新ok[3.1].doc 普 通 高 校 本 科 计 算 机 专 业 特 色 教 材 精 选 四 川 大 学 计 算 机 学 院 国 家 示 范 性 软 件 学 院 精 品 课 程 基 金 青 年 基 金 资 助 项 目 C 语 言 程 序 设 计 (C99 版 ) 陈 良 银 游 洪 跃 李 旭 伟 主 编 李 志 蜀 唐 宁 九 李 涛 主 审 清 华 大 学 出 版 社 北 京 i 内 容 简 介 本 教 材 面 向

More information

untitled

untitled 1 5 IBM Intel 1. IBM 第 1/175 页 第 2/175 页 第 3/175 页 80 第 4/175 页 2. IBM 第 5/175 页 3. (1) 第 6/175 页 第 7/175 页 第 8/175 页 = = 第 9/175 页 = = = = = 第 10/175 页 = = = = = = = = 3. (2) 第 11/175 页 第 12/175 页 第 13/175

More information

新・解きながら学ぶJava

新・解きながら学ぶJava 481! 41, 74!= 40, 270 " 4 % 23, 25 %% 121 %c 425 %d 121 %o 121 %x 121 & 199 && 48 ' 81, 425 ( ) 14, 17 ( ) 128 ( ) 183 * 23 */ 3, 390 ++ 79 ++ 80 += 93 + 22 + 23 + 279 + 14 + 124 + 7, 148, 16 -- 79 --

More information

PowerPoint Presentation

PowerPoint Presentation L o g o Java 线程 中软培训中心 内容概述 了解什么是线程 定义线程 实例化线程 启动线程 同步代码 了解线程的 4 个状态之间的转换关系 专题 继承 Thread 和和实现 Runnable 的比较 线程之间的关系 本章目标 学完以后我们应该可以 : 了解什么是线程 编程定义线程 编程实例化线程 知道如何启动线程 会使用同步代码来保护资源 说出线程的 4 个状态之间的转换关系 程序 进程和线程

More information

自由軟體教學平台

自由軟體教學平台 NCHC Opensource task force DRBL c00hkl00@nchc.gov.tw, steven@nchc.gov.tw National Center for High-Performance Computing http://www.nchc.gov.tw Dec, 2002 1 Outline 1. 2. DRBL 3. 4. Service DHCP, TFTP, NFS,

More information