目录

进程

进程/任务(Prcess/Task)

进程控制块抽象(PCB ProcessControlBlock)

进程间通信(InterProcessCommunication)

线程

使用操作系统提供的api创建线程

中断线程


进程

探讨线程之前,先来了解一下进程

进程/任务(Prcess/Task)

每个应⽤程序运⾏于现代操作系统之上时,操作系统会提供⼀种抽象,好像系统上只有这个程序在运 ⾏,所有的硬件资源都被这个程序在使⽤。这种假象是通过抽象了⼀个进程的概念来完成的。进程是操作系统进⾏资源分配的基本单位。

进程控制块抽象(PCB ProcessControlBlock)

包含进程的各种属性

核心属性

1.PID 进程的标识符,唯一不重复

2.内存指针

一个进程的内存中包含指令和数据,内存指针指明哪部分是数据,那部分是指针

3.文件描述符

进程需要对文件进行读写,进程控制块pcb中存储一系列结构体,描述了文件的具体信息

4.进程的状态

大致分为就绪和阻塞

5.进程的优先级

机器的硬件资源有限,需要多个进程进行调度使用,高优先级有限使用资源

6.进程的上下文

进程在使用过程中中断,需记录位置,返回该进程从记录处开始

7.进程的记账信息

记录每个进程在系统上的运行时间

进程间通信(InterProcessCommunication)

⽬前,主流操作系统提供的进程通信机制有如下:

1. 管道 2. 共享内存 3. ⽂件 4. ⽹络 5. 信号量 6. 信号

由于对进程频繁开启关闭消耗大量资源,引出轻量级的线程

线程

⼀个线程就是⼀个"执⾏流".每个线程之间都可以按照顺序执⾏⾃⼰的代码.多个线程之间"同时"执⾏ 着多份代码。线程中包含tgid,不同的线程拥有同一个tgid,表示属于同一进程。线程是操作系统进行调度的基本单位。

线程分前台线程和后台线程

进程中包含前台线程和后台线程,前台线程占主动话语权,当前台线程关闭时会导致整个进程关闭,后台进程关闭不会影响进程的状态。

使用操作系统提供的api创建线程

一个thread对象唯一对应一个线程

方法1

1.重写Thread中的run方法

class Mythread extends Thread {
    @Override
    public void run() {
        System.out.println("hello world");
    }
}

2.调用start创建线程,间接调用run方法

//法1
//引出对象
        Thread t=new Mythread();
//创建新线程
        t.start();
        System.out.println("hello bit");*/

//法2 匿名内部类
Thread t=new Thread(){
            @Override
            public void run() {
                System.out.println("111");
            }
        };
        t.start();

方法2

实现Runnable接口

/给出一个逻辑,具体进程,线程用不关心
class Myrunnble implements Runnable{
    @Override
    public void run() {
        System.out.println("hello world");
    }
}

创建Thread类实例,调⽤Thread的构造⽅法时将Runnable对象作为target参数

//法1 低耦合
Runnable r=new Myrunnble();
        Thread t=new Thread(r);
        t.start();

//法2 匿名类 低耦合
Thread t=new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("222");
            }
        });
        t.start();

使用lambda表达式

Thread t=new Thread(()->{
    //使用Runnable 匿名函数run
    System.out.println("222");
    try {
        Thread.sleep(100);
    } catch (InterruptedException e) {
        throw new RuntimeException(e);
    }
},"t1");
t.start();

中断线程

方法1

使用标志位running决定线程t 是否继续运行

注:此次lambda中获取外部变量通过变量捕获的方式,即将外部变量拷贝一份到表达式内,且该变量在表达式内不能被改变

public class demo1 {
# 使用全局变量running    
public static boolean running=true;
    public static void main(String[] args) {
# boolean running=true;   false方式
Thread t=new Thread(()->{
            while (running){
                System.out.println("hello thread");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }

            System.out.println("Thread 退出");
        });
        t.start();
        Scanner s=new Scanner(System.in);
        System.out.println("请 input");
        int n=s.nextInt();
        if (n==0){
            running=false;
        }
    }
}

方法2

使用thread的内部标志位

Thread t=new Thread(()-> {
            while (!Thread.currentThread().isInterrupted()) {
                System.out.println("hello thread");
#为防止陷入阻塞, t.interrupted(),可以使阻塞线程唤醒
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        });
        t.start();
        //设置内部变量为false
        t.interrupted();

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐