20201321周慧琳

教材第三四章读书笔记

教材第三四章读书笔记

by 20201321 周慧琳

学习目标

  • 第三章:Unix/Linux进程管理
    第三章的主要涉及Unix/Linux中的进程管理,多任务处理原则,进程概念,解释了Unix/Linux中各进程的来源,包括初始进程、INIT进程、守护进程、登录进程、登录进程以及可供用户执行命令的sh进程。

    对进程的执行模式进行了讲解,描述了用于进程管理的Linux/Unix系统调用,阐明了父进程与子进程的关系,解释了I/O重定向和管道的原则和方法。

    第三章还有需要完成的实践任务,如系统调用命令:fork、wait、exec、exit的掌握,通过exec更改进程执行映像等。

  • 第四章:并发编程
    第四章论述了并发编程,介绍了并行计算的概念,比较了并行算法和顺序算法,解释了线程的原理及其相对于进程的优势。解释了死锁问题,讨论了信号量。

    需要实践的项目是实现用户级线程,可通过该项目实现线程同步的线程连接、互斥量和信号量。

知识图谱的归纳

对于第三、四章繁琐的知识点,利用xmind工具制作了一个知识图谱来强化知识理解

学习收获和心得

第三四章主要在讨论进程和线程,在学习过程中也出现了许多难以理解的词汇,需要积累下来明白各个概念的共性与区别。
执行映像:包含执行代码、数据和堆栈的存储区
任务进程可以互换使用
进程:进程是对映像的执行
系统资源包括:内存空间、I/O设备、CPU时间
PROC结构体:用来表示进程的数据结构

MT:多任务处理系统的简称
进程同步:一个操作系统包含许多并发进程,这些进程可以彼此交互。进程同步是指控制和协调进程交互以确保其正确执行所需的各项规则和机制。
进程终止:第2章已经提到,进程死亡(终止)有正常终止,异常终止两种形式
管道:用于进程交换数据的单向进程间通信通道
pid:标识一个进程的进程ID编号
priority:进程调度优先级

以下是我重点学习的内容:

  • fork()创建子进程
  • 一个现有进程可以调用fork函数创建一个新进程。由fork创建的新进程被称为子进程(child process)。fork函数被调用一次但返回两次。两次返回的唯一区别是子进程中返回0值而父进程中返回子进程ID。
    子进程是父进程的副本,它将获得父进程数据空间、堆、栈等资源的副本。注意,子进程持有的是上述存储空间的“副本”,这意味着父子进程间不共享这些存储空间。
#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
 
int main(int argc,char *argv[]){
    pid_t pid=fork();
    if ( pid < 0 ) {
        fprintf(stderr,"错误!");
    } else if( pid == 0 ) {
        printf("子进程空间");
        exit(0);
    } else {
        printf("父进程空间,子进程pid为%d",pid);
    }
    // 可以使用wait或waitpid函数等待子进程的结束并获取结束状态
    exit(0);
}
  • 认识环境变量
    环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数,如:临时文件夹位置和系统文件夹位置等。
    环境变量是在操作系统中一个具有特定名字的对象,它包含了一个或者多个应用程序所将使用到的信息。例如Windows和DOS操作系统中的path环境变量,当要求系统运行一个程序而没有告诉它程序所在的完整路径时,系统除了在当前目录下面寻找此程序外,还应到path中指定的路径去找。用户通过设置环境变量,来更好的运行进程。
    Linux的环境变量和Windows的还是有一些区别。需要再花时间熟悉下。

    可以通过以上方法来查看本机的具体环境变量设置

pthread_cancel()不能杀死线程

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <unistd.h>
  4 #include <pthread.h>
  5 #include <string.h>
  6 
  7 void *func(void *arg){
  8     while(1);
  9     return NULL;
 10 }
 11 int main(){
 12     printf("main:pid=%d,tid=%lu\n",getpid(),pthread_self());
 13 
 14     pthread_t tid;
 15     int ret = pthread_create(&tid,NULL,func,NULL);
 16     if(ret != 0){
 17         fprintf(stderr,"pthread_create error:%s\n",strerror(ret));
 18         return 1;
 19     }
 20 
 21     ret = pthread_cancel(tid);
 22     if(ret != 0){
 23         fprintf(stderr,"pthread_cancel error:%s\n",strerror(ret));
 24         return 2;
 25     }
 26 
 27     pthread_exit((void*)0);
 28 
 29     return 0;
 30 }

原因:

使用pthread_cancel()终止线程,需要线程中存在取消点。

大致是需要线程中有陷入内核的操作,才会存在取消点

如果想要用pthread_cancel()终止一个没有陷入内核操作的线程,就需要手动添加取消点

在while循环中加入,pthread_testcancel()即可用pthread_cancel()杀死该线程

  7 void *func(void *arg){
  8     while(1) pthread_testcancel();
  9     return NULL;
 10 }

posted on 2022-09-11 15:43  20201321周慧琳  阅读(12)  评论(0编辑  收藏  举报