C# 进程(Process)与线程(Thread)的理解及运用

线程的理解及运用

  • 一、进程、线程和协程的理解
    • 1、进程、线程、协程的区别和定义
    • 2、串行,并行和并发的基本概念
  • 二、线程的使用
  • 三、进程(Process)的使用

一、进程、线程和协程的理解

在unity中可以使用多线程去做 解压资源、更新资源等操作。因为单开线程的话 不会影响主线程卡顿,这样UI就不会卡了。但是开的线程里边不能执行unity主线程的mono代码。线程启动后,执行完毕自动结束该线程、可以同时启动多个线程做事。

比如微信,在启动的时候就会开两个线程。微信有两个进程分别是com.tencent.mm(A), com.tencent.mm:push(B),这里可以把A进程当成是主要处理UI变化的进程,B进程是处理消息同步的进程,在把A进程关掉之后,如果没有消息触发,B进程是不会唤醒A进程,而当B进程被干掉后,微信的做法是A进程也同时被干掉了,个人猜测微信的做法可能是基于这种情况,如果只有A进程,那是收不到消息的,因为消息处理都是在B进程进行的,这就会出现很多bug。

实时通讯软件需要有一个后台服务常驻,但是通常情况下单一进程容易被干掉,双进程的好处一个是可以实现相互唤起,另一个好处单独进程去处理消息更不容易出现消息的阻塞现象,这点对实时通讯软件还是比较关键的。

1、进程、线程、协程的区别和定义

进程(Process)是一个实体,是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。在早期面向进程设计的计算机结构中,进程是程序的基本执行实体;在当代面向线程设计的计算机结构中,进程是线程的容器。程序是指令、数据及其组织形式的描述,进程是程序的实体。

线程(Thread)是进程中的实际运作单位,进程的基本单元;一个进程可以包含若干个线程,某个程序开始时执行时,进程的第一个线程被默认为该进程的主线程。

协程(IEnumerator)是一个线程执行,两个子过程通过相互协作完成某个任务。协程和子程序调用很像,但协程是在子程序内部中断去执行别的子程序,适当时候返回接着执行,中断有别于函数调用。

线程之间的联系:
一个进程中可以创建多个线程,多线程之间是迸发执行的,一个线程可以终止其他线程或者开启其他线程。但是每个线程之间就算是共享了数据,他们也都拥有自己独立的堆栈空间和执行顺序。

多线程的优点:
每个线程都有独立的堆栈空间,多线程可可同时执行多个功能,提高进程的运行效率。目前电脑都是多核多CPU的,一个CPU在同一时刻只能运行一个线程,但是多个CPU在同一时刻就可以运行多个线程。

多线程的缺点:
线程太多了不好对其管理控制,容易让程序崩溃,虽然多线程提高了运行效率,但是同时也提高了占用内存的空间。

2、串行,并行和并发的基本概念

C# 进程(Process)与线程(Thread)的理解及运用_第1张图片

二、线程的使用

引用:System.Threading
线程类:Thread

创建一个新线程:
Thread newThread=new Thread(new ThreadStart());*
注:ThreadStart是一个委托,可传入该线程的执行事件

thread.Start(): 让一个线程开始执行
thread.Abort(): 终止线程的运行
Thread.Sleep(float timer): 使线程挂起一段时间,timer=1000就相当于该线程在此处暂停1s后再继续执行

using UnityEngine;
using System.Threading;

public class ThreadTest:MonoBehaviour
{
     
    void StartThread()
    {
     
        Thread athread = new Thread(new ThreadStart(goThread));

        athread.IsBackground = true;//控制该线程随主线程的退出而退出,防止出现后台线程。相反需要后台线程就设为false
        athread.Start();
    }
    void Awake()
    {
     
    	Debug.Log("系统内核数:"+SystemInfo.processorCount);
        StartThread();
    }

    object lockd = new object();
    void goThread()
    {
     
        int index = 0;
        while (true)
        {
     
            //防止其他线程访问当前线程使用的数据
            //lockd 不能是值类型,也不能是string
            lock (lockd)
            {
     
                Debug.Log("in thread" + index);
                index++;
                if (index == 10)
                {
     
                    Thread.Sleep(5000);//   将当前线程挂起指定的时间 毫秒  时间结束后 继续执行下一步  和yield类似
                }
                else if (index == 20)
                {
     
                    break;//该函数执行完自动结束该线程
                }
            }
        }
    }

}

1、当在主线程中创建了一个线程,那么该线程的IsBackground默认是设置为FALSE的。

2、当主线程退出的时候,IsBackground=FALSE的线程还会继续执行下去,直到线程执行结束。

3、只有IsBackground=TRUE的线程才会随着主线程的退出而退出

注:关于lock关键字,可参考这篇博客:https://www.cnblogs.com/jintianhu/archive/2010/11/19/1881494.html

再来个双线程案例:


	Thread thread_Print;//这是负责打印文字的线程

    Thread thread_Abort;//这是一个终止线程

    private void Start()
    {
     
        EnableThread();
    }

    //开启线程
    void EnableThread()
    {
     
        //首先要创建一个线程,执行文字的打印
        thread_Print = new Thread(new ThreadStart(PrintWord));

        //然后调用Start函数启动该线程
        thread_Print.Start();

        //我们再来创建一个终止线程,在30s之后,停止打印文字的线程
        thread_Abort = new Thread(new ThreadStart(() =>
        {
     
            Thread.Sleep(30000);

            print("停止线程的执行!");

            //文字打印的线程执行停止
            AbortThread();
        }));

        //别忘了启动终止线程
        thread_Abort.Start();
    }

    /// 
    /// 每隔5秒循环打印文字
    /// 
    void PrintWord()
    {
     
        while (true)
        {
     
            print("Good Boy!");
            Thread.Sleep(5000);
        }
    }

    /// 
    /// 终止线程的执行
    /// 
    void AbortThread()
    {
     
        //终止文字打印线程的执行
        if (thread_Print != null)
        {
     
            thread_Print.Abort();            
        }

        //终止 控制停止的线程
        if (thread_Abort != null)
        {
     
            thread_Abort = null;
        }
    }

运行后的结果如下图:
C# 进程(Process)与线程(Thread)的理解及运用_第2张图片

三、进程(Process)的使用

Process类
负责启动和停止本机进程,获取或设置进程优先级,确定进程是否响应,是否已经退出,以及获取系统正在运行的所有进行列表和各进程资源占用情况。也可以查询远城计算机上进程相关信息,包括进程内的线程集合、加载模块(.dll文件和.exe文件)和性能信息(如当前进程使用的内存量)

具体可参考此博客:C#的 Process类

你可能感兴趣的