尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

【00016】

【00016】 4.3 进程和线程1. 进程1进程概念程序存放在外存中的一段代码的集合进程是程序动态执行的过程包括创建、调度、消亡2进程命令top根据CPU占用率查看进程信息PID唯一区分进程的ID号PPID父进程的ID号ps -ef查看进程信息pstree查看进程关系ps -aux查看进程运行状态kill杀死进程任务kill -9 进程PIDkillall -9 进程名后台执行任务./a.out 查看后台执行的任务jobs将后台任务放到前台执行fg 编号查看终端下的前后台任务ps修改进程优先级nice -n 优先级 进程任务renice -n 优先级 进程PID3 进程的创建1. 32位操作系统下进程占0 - 4G虚拟内存空间可以划分为文本段、数据段及系统数据段文本段指令数据段字符串常量、未初始化全局变量/静态变量、初始化的全局变量/静态变量系统数据段堆区、栈区2. 特性进程空间是独立的每个进程独享进程空间所有进程共享0-4G虚拟内存空间分时复用3. 进程调度1多个进程任务需要同时运行2常见进程调度算法1. 先来先执行后来后执行2. 高优先级调度算法3. 时间片轮转调度算法宏观并行微观串行4. 多级队列反馈调度算法5. 负载均衡调度算法3时间片CPU在进程任务中执行的一小段时间称为时间片4进程状态1. 就绪态R没有被CPU轮转到的正在执行的任务2. 运行态R正在被CPU执行的任务3. 可唤醒等待态S由于缺少资源让程序暂时挂起的状态等待过程中可以被唤醒4. 不可唤醒等待态D等待过程中不会被唤醒称为不可唤醒等待态5. 停止态T由于系统需要让进程任务暂停则将进程设置为停止态6. 僵尸态Z进程代码执行结束空间没有被回收7. 结束态X代码执行结束空间被回收的时刻4进程相关的函数接口1. forkpid_t fork(void);功能创建一个子进程空间参数缺省返回值成功父进程中返回子进程的PID子进程中返回0失败返回-12.getpidpid_t getpid(void);功能返回调用进程的进程ID号3.exitvoid exit(int status);功能进程结束主函数中调用exit与调用return效果相同函数体内调用return函数结束调用exit让进程结束5进程的消亡1.僵尸进程产生原因进程代码执行结束空间没有被回收就会成为僵尸进程2.如何避免产生僵尸进程让父进程先结束子进程称为孤儿进程被init进程收养子进程结束init进程回收子进程空间避免产生僵尸进程子进程结束父进程回收子进程空间就能避免子进程称为僵尸进程6 进程回收函数接口1.waitpid_t wait(int *wstatus);功能回收子进程空间参数wstatus存子进程结束状态空间的首地址返回值成功返回回收到的子进程的PID失败返回-1WIFEXITED(wstatus)检测子进程是否正常退出WEXITSTATUS(wstatus)获得子进程退出时的值WIFSIGNALED(wstatus)检测子进程是否被信号杀死WTERMSIG(wstatus)获得杀死信号的编号wait回收子进程空间避免子进程成为僵尸进程wait具有阻塞功能能够实现多任务同步2.waitpidpid_t waitpid(pid_t pid, int *wstatus, int options);功能回收指定子进程的空间参数pid:要回收的子进程的PIDwstatus存放子进程结束状态空间的首地址options0 阻塞回收WNOHANG 非阻塞回收返回值成功返回回收到的进程的ID号失败返回-1WNOHANG设置非阻塞如果子进程没有结束返回03.exec函数族extern char **environ;int execl(const char *path, const char *arg, .../* (char *) NULL*/);int execlp(const char *file, const char *arg, .../* (char *) NULL*/);int execle(const char *path, const char *arg, .../*, (char *) NULL,char * const envp[] */);int execv(const char *path, char *const argv[]);int execvp(const char *file, char *const argv[]);int execvpe(const char *file, char *const argv[], char *constenvp[]);功能利用进程空间执行另一段代码参数path:路径名file:文件名l:参数以列表形式传递v:参数以指针数组形式传递p:在系统路径PATH下查找文件名e:执行另一段代码时更新进程的环境变量返回值成功会执行另一份代码失败返回-1环境变量进程在执行代码过程中临时存放信息的变量称为环境变量4.setenvint setenv(const char *name, const char *value, int overwrite);功能设置环境变量的值参数name:环境变量名称value设置的环境变量的值overwrite:非0 覆盖0 不会覆盖返回值成功返回0失败返回-12.线程1线程线程是一个轻量的进程一个任务创建、调度、消亡的过程2进程和线程区别1. 进程是操作系统资源分配的最小单元进程独占0-4G虚拟内存空间可以划分为文本段、数据段、系统数据段每个进程独享以上区域线程位于进程空间内部线程只有独立的栈空间其余的堆区、数据区、文本区与进程内其余线程共享2. 线程是操作系统任务调度的最小单元3线程创建每个线程拥有属于自己的栈空间默认为8M其余空间与进程内其余线程共享局部变量独享全局变量、静态变量、字符串常量、堆区都是共享的4线程调度与进程调度保持一致宏观并行微观串行5 线程消亡线程结束必须回收线程空间否则会产生僵尸线程6线程函数接口进程 线程fork pthread_createexit pthread_exitwait pthread_join7函数原型1. pthread_createint pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *),void*arg);功能在进程中创建一个线程参数thread:存放线程ID空间的首地址attr:线程的属性栈空间大小、优先级、分离/加入属性默认属性传NULLstart_routine函数指针指向线程要执行的函数arg:对线程函数的传参返回值成功返回0失败返回错误码2. pthread_exitvoid pthread_exit(void *retval);功能结束线程任务参数retval线程结束时的状态返回值缺省3. pthread_joinint pthread_join(pthread_t thread, void **retval);功能回收线程空间参数thread:回收线程的TIDretval:存放线程结束状态空间的首地址返回值成功返回0失败返回错误码8线程分离属性线程结束后系统自动回收线程空间而无需调用pthread_join回收空间1. pthread_attr_initint pthread_attr_init(pthread_attr_t *attr);功能对线程属性进行初始化2. pthread_attr_destroyint pthread_attr_destroy(pthread_attr_t *attr);功能线程属性销毁3. pthread_attr_setdetachstateint pthread_attr_setdetachstate(pthread_attr_t *attr, intdetachstate);功能设置线程属性9多进程和多线程优缺点1. 运行效率多线程 多进程多线程在同一进程空间内部任务调度效率更高2. 安全多进程 多线程进程空间是独立的一个进程异常结束不会影响其余进程线程位于进程空间内部一个线程异常结束会导致进程结束其余线程也随之结束3. 通信实现多线程 多进程线程位于进程空间内部共享进程的文本段、数据段全局变量、静态变量、字符串常量、堆区所以可以通过共享空间实现通信进程空间是独立的没有共享空间无法通信4. 通信编程复杂程度多进程 多线程多线程使用全局变量通信会引入资源竞争问题需要加锁来解决多进程空间独立的没有共享空间需要使用第三方机制来完成进程间通信3.线程间通信1线程间通信方式线程使用全局变量可以实现通信多线程同时使用全局变量会引入资源竞争需要通过互斥锁解决资源竞争问题2概念原子操作不能被CPU任务调度打断的一次最小的操作称为原子操作临界代码/临界区加锁解锁中间的代码这段代码用户不会被同时执行3互斥锁1. 函数接口1pthread_mutex_initint pthread_mutex_init(pthread_mutex_t *restrict mutex,const pthread_mutexattr_t *restrict attr);功能初始化互斥锁参数mutex:互斥锁空间首地址attr:互斥锁的属性默认属性NULL返回值成功返回0失败返回-12pthread_mutex_destroyint pthread_mutex_destroy(pthread_mutex_t *mutex);功能互斥锁销毁3pthread_mutex_lockint pthread_mutex_lock(pthread_mutex_t *mutex);功能互斥锁上锁4pthread_mutex_unlockint pthread_mutex_unlock(pthread_mutex_t *mutex);功能互斥锁解锁4死锁1. 由于多个锁的加锁解锁导致线程无法继续执行的状态称为死锁2. 死锁产生的四个必要条件互斥条件不可剥夺条件请求保持循环等待3. 避免产生死锁使用pthread_mutex_trylock替代pthread_mutex_lock多把锁加锁顺序保持一致5信号量1. 信号量是这一种资源在程序运行过程中代码、变量、CPU、内存都可以看成是一种资源2. 资源一定是有限的资源只能被初始化、销毁、申请和释放3. 函数接口1 sem_initint sem_init(sem_t *sem, int pshared, unsigned int value);功能初始化信号量参数sem:信号量的地址pshared:0同一进程的线程间共享非0进程间共享value:初始化的值返回值成功返回0失败返回-12sem_destoryint sem_destroy(sem_t *sem);功能销毁信号量参数sem:信号量的首地址返回值成功返回0失败返回-13sem_waitint sem_wait(sem_t *sem);功能申请信号量如果资源数0则让资源数-1如果资源数 0,阻塞等待直到资源 0 才能申请到资源继续向下执行参数sem:信号量空间首地址返回值成功返回0失败返回-14sem_postint sem_post(sem_t *sem);功能释放资源让资源数1参数sem:信号量空间首地址返回值成功返回0失败返回-1
返回列表