一、基本概念
先说什么是进程
1、进程(Process)是Windows系统中的一个基本概念,它包含着一个运行程序所需要的资源。一个正在运行的应用程序在操作系统中被视为一个进程,进程可以包括一个或多个线程。线程是操作系统分配处理器时间的基本单元,在进程中可以有多个线程同时执行代码。进程之间是相对独立的,一个进程无法访问另一个进程的数据(除非利用分布式计算方式),一个进程运行的失败也不会影响其他进程的运行,Windows系统就是利用进程把工作划分为多个独立的区域的。进程可以理解为一个程序的基本边界。是应用程序的一个运行例程,是应用程序的一次动态执行过程。
下图就是进程的显示
那什么是线程,从哪里看
2、线程(Thread)是进程中的基本执行单元,是操作系统分配CPU时间的基本单位,一个进程可以包含若干个线程,在进程入口执行的第一个线程被视为这个进程的主线程。在.NET应用程序中,都是以Main()方法作为入口的,当调用此方法时系统就会自动创建一个主线程。线程主要是由CPU寄存器、调用栈和线程本地存储器(Thread Local Storage,TLS)组成的。CPU寄存器主要记录当前所执行线程的状态,调用栈主要用于维护线程所调用到的内存与数据,TLS主要用于存放线程的状态信息。
线程就是后台进程可在下图的任务管理器查看
3、多线程
多线程的优点:
(1)可以同时完成多个任务;可以使程序的响应速度更快;
(2)可以让占用大量处理时间的任务或当前没有进行处理的任务定期将处理时间让给别的任务;可以随时停止任务;可以设置每个任务的优先级以优化程序性能。
多线程的缺点:
(1)线程也是程序,所以线程需要占用内存,线程越多,占用内存也越多。
(2)多线程需要协调和管理,所以需要占用CPU时间以便跟踪线程。
(3)线程之间对共享资源的访问会相互影响,必须解决争用共享资源的问题。
(4)线程太多会导致控制太复杂,最终可能造成很多程序缺陷。
当启动一个可执行程序时,将创建一个主线程。例如启动一个C#程序,就创建一个线程,此线程执行程序中以Main方法开始和结束的代码,Main()方法直接或间接执行的每一个命令都有默认线程(主线程)执行,当Main()方法返回时此线程也将终止。
在C#中,线程是使用Thread类处理的,该类在System.Threading命名空间中
具体代码如下
Thread thread=new Thread(new ThreadStart(function));//创建线程
thread.Start(); //启动线程
Thread thread=new Thread(new ParameterizedThreadStart(function));//创建线程
thread.Start(value); //启动线程
ThreadStart的方法是不带参数的线程比较常用,而ParameterizedThreadStart是带参数的。一般用到的就这两种方法
一般窗体的控件是属于主线程的,你另开线程去控制控件是会报错的,你只能用两种方法去控制控件
1、Control.CheckForIllegalCrossThreadCalls = false;
使用上面代码是取消跨线程的访问,但这种方法是不允许的也是不安全的所以不提倡。
2、使用委托
private delegate void setTextValue(int value);
//声明委托
private setTextValue set;
private void button1_Click(object sender, EventArgs e)
{
set = new setTextValue(SetValue);
Thread thread = new Thread(new ThreadStart(Test));//创建一个线程去执行这个方法
thread.IsBackground = true;//将线程设置为后台线程
thread.Start();//执行
}
private void Test()
{
for (int i = 0; i < 10000; i++)
{
//使用委托
textBox1.Invoke(set, i);
}
}
/// <summary>
/// 定义委托的方法
/// </summary>
/// <param name="value"></param>
private void SetValue(int value)
{
textBox1.Text = value.ToString();
}
线程同步
实现线程同步只要在线程那里加上锁就可以了
public int num = 1;
public void Buy()
{
lock (this)
{
int tmp = num;
if (tmp > 0)
{
Thread.Sleep(1000);
num -= 1;
textBox1.Text = $"售出一个西瓜,还剩余{num}个 ";
}
else
{
textBox1.Text = "西瓜已售完";
}
}
}
还有一种创建多线程的方法
List<Task> tasks = new List<Task>();
var task = Task.Factory.StartNew(() =>{});
tasks.Add(task);
Task.WaitAll(tasks.ToArray());//等待Tasks里的所有线程执行完成才能往下走
Task.WaitAny(tasks.ToArray());//任意一条线程执行完成才能往下走