队列
队列的定义与操作
- 队列
queue
的定义:入队在一端(队尾)进行而出队在另一端(队首)进行的线性表。即:先进先出的线性表
- 队列的操作
- 入队操作:将数据元素值插入队尾
- 出队操作:移除队首的数据元素
- 是否为空:判断队中是否包含数据元素
- 得到队长:获取队中实际包含数据元素的个数
- 清空操作:移除队中的所有数据元素
- 获取队首元素
//interface
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DataStruct2020.demo
{
public interface IQueue<T> where T : IComparable<T>
{
void EnQueue(T data);
void DeQueue();
void Clear();
bool IsEmpty();
int Length { get; }
T QueueFront { get; }
}
}
- 涉及大量元素的移动
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DataStruct2020.demo
{
public class SeqQueue<T> : IQueue<T> where T : IComparable<T>
{
private SeqList<T> _lst;
public SeqQueue(int max)
{
if (max <= 0)
throw new ArgumentOutOfRangeException();
_lst = new SeqList<T>(max);
}
public int Length
{
get { return _lst.Length; }
}
public int MaxSize
{
get { return _lst.MaxSize; }
}
public T QueueFront
{
get
{
if (_lst.Length == 0)
throw new Exception("队列为空");
return _lst[0];
}
}
public void Clear()
{
_lst.Clear();
}
public void DeQueue()
{
if (Length == 0)
throw new Exception("队列为空");
_lst.Remove(0);
}
public void EnQueue(T data)
{
if (MaxSize == Length)
throw new Exception("队列已满");
_lst.Insert(_lst.Length, data);
}
public bool IsEmpty()
{
return _lst.IsEmpty();
}
}
}
//客户端代码
IQueue<Student> queue = new SeqQueue<Student>(100);
queue.EnQueue(new Student("test01", 20, 10086));
queue.EnQueue(new Student("test02", 23, 95588));
queue.EnQueue(new Student("test03", 22, 95598));
int count = queue.Length;
for (int i = 0; i < count; i++)
{
Console.WriteLine(queue.QueueFront);
queue.DeQueue();
}//通常使用while循环,for循环也可以的
//
Name :test01,Age:20
Name :test02,Age:23
Name :test03,Age:22
- 循环队列:利用数组采用循环的方式实现的队列(不移动元素移动窗口)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DataStruct2020.demo
{
public class CSeqQueue<T> : IQueue<T> where T : IComparable<T>
{
private int _pFront;
private int _pRear;
private int _length;
private int _maxSize;
private T[] _dataset;
public int Length
{
get { return _length; }
}
public int Maxsize
{
get { return _maxSize; }
}
public CSeqQueue(int max)
{
if (max <= 0)
throw new ArgumentOutOfRangeException();
_pFront = 0;
_pRear = 0;
_length = 0;
_maxSize = max;
_dataset = new T[_maxSize];
}
public T QueueFront
{
get
{
if (_length == 0)
throw new Exception("队列为空");
return _dataset[_pFront];
}
}
public void Clear()
{
_length = 0;
_pRear = 0;
_pFront = 0;
}
public void DeQueue()
{
if(_length == 0)
throw new Exception("队列为空");
_pFront = (_pFront + 1) % _maxSize;
_length--;
}
public void EnQueue(T data)
{
if (_maxSize == _length)
throw new Exception("队列已满");
_dataset[_pRear] = data;
_pRear = (_pRear + 1) % _maxSize;
_length++;
}
public bool IsEmpty()
{
return _length == 0;
}
}
}
IQueue<Student> queue = new CSeqQueue<Student>(100);
queue.EnQueue(new Student("test01", 20, 10086));
queue.EnQueue(new Student("test02", 23, 95588));
queue.EnQueue(new Student("test03", 22, 95598));
int count = queue.Length;
while (queue.IsEmpty() == false)
{
Console.WriteLine(queue.QueueFront);
queue.DeQueue();
}
//
Name :test01,Age:20
Name :test02,Age:23
Name :test03,Age:22
链式存储
- 链队:利用单链表实现的队列
//单链表
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DataStruct2020.demo
{
public class LinkQueue<T> : IQueue<T> where T : IComparable<T>
{
private SLinkList<T> _lst;
public LinkQueue()
{
_lst = new SLinkList<T>();
}
public int Length
{
get
{
return _lst.Length;
}
}
public T QueueFront
{
get
{
if (_lst.IsEmpty() == true)
throw new Exception("队列为空");
return _lst[0];
}
}
public void Clear()
{
_lst.Clear();
}
public void DeQueue()
{
if (_lst.IsEmpty() == true)
throw new Exception("队列为空");
_lst.Remove(0);
}
public void EnQueue(T data)
{
_lst.InsertAtRear(data);
}
public bool IsEmpty()
{
return _lst.IsEmpty();
}
}
}
IQueue<Student> queue = new LinkQueue<Student>();
queue.EnQueue(new Student("test01", 20, 10086));
queue.EnQueue(new Student("test02", 23, 95588));
queue.EnQueue(new Student("test03", 22, 95598));
int count = queue.Length;
while (queue.IsEmpty() == false)
{
Console.WriteLine(queue.QueueFront);
queue.DeQueue();
}
//
Name :test01,Age:20
Name :test02,Age:23
Name :test03,Age:22
- 利用循环队列(执行效率更高)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DataStruct2020.demo
{
public class LinkQueue<T> : IQueue<T> where T : IComparable<T>
{
//private SLinkList<T> _lst;//单链表
private CLinkList<T> _lst;
public LinkQueue()
{
_lst = new CLinkList<T>();
}
public int Length
{
get
{
return _lst.Length;
}
}
public T QueueFront
{
get
{
if (_lst.IsEmpty() == true)
throw new Exception("队列为空");
return _lst[0];
}
}
public void Clear()
{
_lst.Clear();
}
public void DeQueue()
{
if (_lst.IsEmpty() == true)
throw new Exception("队列为空");
_lst.Remove(0);
}
public void EnQueue(T data)
{
_lst.InsertAtRear(data);
}
public bool IsEmpty()
{
return _lst.IsEmpty();
}
}
}
进程与线程
- 进程的定义:进程是程序的动态执行过程,是系统进行资源分配和调度的基本单位
- C#对进程的管理:
Process
- 所在命名空间
using System.Diagnostics
- 进程的创建:
Process pros = new Process();//初始化Process类的新实例
- 进程的启动
pros.StartInfo.FileName = "notepad.exe";//获取或设置要启动的应用程序或文档
pros.StartInfo.WindowStyle = ProcessWindowStyle.Minimized;//获取或设置启动进程时使用的窗口状态
pros.Start();//启动此Process组件的StartInfo属性指定的进程资源,并将其与该组件关联
- 进程的查询
Process[] process = Process.GetProcesses();//为本地计算机上的每个进程资源创建一个新的Process组件
foreach(Process p in process)
{
int id = p.Id;//获取关联进程的唯一标识符
string name = p.ProcessName;//获取该进程的名称
long memory = p.WorkingSet64;//获取为关联的进程分配的物理内存量
if(name != "Idle")
{
DataTime startTime = p.StartTime;//获取关联进程启动的时间
}
}
- 进程的终止
process = Process.GetProcessesByname("notepad");//创建新的Process组件的数组,并将它们与本地计算机上共享指定的进程名称的所有进程资源关联
foreach(Process p in process)
{
p.WaitForExit(1000);//指示Process组件在指定的毫秒数内等待关联进程退出
p.Kill();//立即停止关联的进程
}
- 线程的定义:同一个进程又可划分为若干个独立的执行流称之为线程,线程是CPU进行资源分配和调度的基本单位
- C#对线程的管理(
Thread
) - 所在命名空间
using System.Threading
- 线程的创建
Thread thread1 = new Thread(enterPoint1);//初始化Thread类的新实例
Thread thread2 = new Thread(enterPoint2);//enterPoint1,enterPoint2是线程要执行的方法
- 线程的启动
thread1.Start();//导致操作系统将当前实例的状态更改为 ThreadState.Running
thread2.Start();
- 线程的休眠
Thread.Sleep(1000);//将当前线程挂起指定的时间。该语句线程休眠1秒钟
- 线程的合并
thread1.Join();//在继续执行标准的COM和SendMessage消息泵处理期间,阻止调用线程,直到某个线程终止为止
thread2.Join(1000);//在继续执行标准的COM和SendMessage消息泵处理期间,阻止调用线程,直到某个线程终止或经过了指定时间为止
//若thread2运行过程中需要等待thread1结束后才能继续执行,可在thread2的模块中调用thread1.Join()这时thread2处于阻塞状态
- 线程的终止
thread.About();//在调用此方法的线程上引发Threading.ThreadAbortException.以开始终止此线程的过程。调用此方法通常会终止线程
ex1
using System;
using System.Threading;
namespace demo.thread
{
class Program
{
static void Add()
{
int sum = 0;
for (int i = 0; i <= 100; i++)
{
sum += i;
Console.WriteLine("sum:{0}",sum);
}
}
static void SubStract()
{
int div = 5050;
for (int i = 0; i <= 100; i++)
{
div -= i;
Console.WriteLine("div:{0}",div);
}
}
static void Main(string[] args)
{
Thread thread1 = new Thread(Add);
Thread thread2 = new Thread(SubStract);
thread1.Start();
thread2.Start();
thread1.Join();
thread2.Join();
Console.WriteLine("Main Thread Finish");
}
}
}
- 线程同步的定义
ex2
(不同步)
using System;
using System.Threading;
namespace demo.thread
{
public class Resource
{
private int context = 0;
public void Write()
{
context++;
Console.WriteLine("Writer:{0}", context);
}
public void Read()
{
Console.WriteLine("Reader:{0}", context);
}
}
public class Writer
{
private Resource rec;
public Writer(Resource r)
{
rec = r;
}
public void Run()
{
for (int i = 0; i < 10; i++)
rec.Write();
}
}
public class Reader
{
private Resource rec;
public Reader(Resource r)
{
rec = r;
}
public void Run()
{
for (int i = 0; i < 10; i++)
rec.Read();
}
}
class Program
{
static void Main(string[] args)
{
Resource r = new Resource();
Writer writer = new Writer(r);
Reader reader = new Reader(r);
Thread wThread = new Thread(writer.Run);
Thread rThread = new Thread(reader.Run);
wThread.Start();
rThread.Start();
}
}
}
//
Reader:1
Reader:1
Reader:1
Reader:1
Reader:1
Reader:1
Reader:1
Reader:1
Reader:1
Reader:1
Writer:1
Writer:2
Writer:3
Writer:4
Writer:5
Writer:6
Writer:7
Writer:8
Writer:9
Writer:10
- 线程同步的方法1:利用
lock
关键字用法:
private object obj = new object();
public void Function()
{
lock(obj)
{
//需要同步的代码段
}
}
using System;
using System.Threading;
namespace demo.thread1
{
public class Resource
{
private int context = 0;
private object obj = new object();
public void Write()
{
lock (obj)
{
context++;
Console.WriteLine("Writer:{0}", context);
}
}
public void Read()
{
lock (obj)
{
Console.WriteLine("Reader{0}", context);
}
}
public class Writer
{
private Resource rec;
public Writer(Resource r)
{
rec = r;
}
public void Run()
{
for (int i = 0; i < 10; i++)
rec.Write();
}
}
public class Reader
{
private Resource rec;
public Reader(Resource r)
{
rec = r;
}
public void Run()
{
for (int i = 0; i < 10; i++)
rec.Read();
}
}
class Program
{
static void Main(string[] args)
{
Resource r = new Resource();
Writer writer = new Writer(r);
Reader reader = new Reader(r);
Thread wThread = new Thread(writer.Run);
Thread rThread = new Thread(reader.Run);
wThread.Start();
rThread.Start();
}
}
}
}
//
Reader0
Reader0
Reader0
Reader0
Reader0
Reader0
Reader0
Reader0
Reader0
Reader0
Writer:1
Writer:2
Writer:3
Writer:4
Writer:5
Writer:6
Writer:7
Writer:8
Writer:9
Writer:10
- 线程同步的方法2:利用
Monitor
类
private object obj = new object();
public void Function()
{
Monitor.Enter(obj);//在指定对象上获取排他锁
//需要同步的代码段
Monitor.Exit(obj);//释放指定对象上的排他锁
}
using System;
using System.Threading;
namespace demo.thread.monitor
{
public class Resource
{
private int context = 0;
private object obj = new object();
public void Write()
{
Monitor.Enter(obj);
context++;
Console.WriteLine("Writer:{0}", context);
Monitor.Exit(obj);
}
public void Read()
{
Monitor.Enter(obj);
Console.WriteLine("Reader{0}", context);
Monitor.Exit(obj);
}
public class Writer
{
private Resource rec;
public Writer(Resource r)
{
rec = r;
}
public void Run()
{
for (int i = 0; i < 10; i++)
rec.Write();
}
}
public class Reader
{
private Resource rec;
public Reader(Resource r)
{
rec = r;
}
public void Run()
{
for (int i = 0; i < 10; i++)
rec.Read();
}
}
class Program
{
static void Main(string[] args)
{
Resource r = new Resource();
Writer writer = new Writer(r);
Reader reader = new Reader(r);
Thread wThread = new Thread(writer.Run);
Thread rThread = new Thread(reader.Run);
wThread.Start();
rThread.Start();
}
}
}
}
//
Writer:1
Writer:2
Writer:3
Writer:4
Writer:5
Writer:6
Writer:7
Writer:8
Writer:9
Writer:10
Reader10
Reader10
Reader10
Reader10
Reader10
Reader10
Reader10
Reader10
Reader10
Reader10
wThread
线程写入数据后,rThread
线程读取数据
using System;
using System.Threading;
namespace demo.thread.ex3
{
public class Resource
{
private int context = 0;
private bool readflag = false;
public void Write()
{
while (readflag == true)//只能读不能写
;
context++;
Console.WriteLine("Writer:{0}", context);
readflag = true;
}
public void Read()
{
while (readflag == false)
;
Console.WriteLine("Reader{0}", context);
readflag = false;
}
public class Writer
{
private Resource rec;
public Writer(Resource r)
{
rec = r;
}
public void Run()
{
for (int i = 0; i < 10; i++)
rec.Write();
}
}
public class Reader
{
private Resource rec;
public Reader(Resource r)
{
rec = r;
}
public void Run()
{
for (int i = 0; i < 10; i++)
rec.Read();
}
}
class Program
{
static void Main(string[] args)
{
Resource r = new Resource();
Writer writer = new Writer(r);
Reader reader = new Reader(r);
Thread wThread = new Thread(writer.Run);
Thread rThread = new Thread(reader.Run);
wThread.Start();
rThread.Start();
}
}
}
}
//
Writer:1
Reader1
Writer:2
Reader2
Writer:3
Reader3
Writer:4
Reader4
Writer:5
Reader5
Writer:6
Reader6
Writer:7
Reader7
Writer:8
Reader8
Writer:9
Reader9
Writer:10
Reader10
- 利用
Monitor
using System;
using System.Threading;
namespace demo.thread.ex4
{
public class Resource
{
private int context = 0;
private object obj = new object();
private bool readflag = false;
public void Write()
{
Monitor.Enter(obj);
if (readflag == true)//只能读不能写
Monitor.Wait(obj);
context++;
Console.WriteLine("Writer:{0}", context);
readflag = true;
Monitor.Pulse(obj);
Monitor.Exit(obj);
}
public void Read()
{
Monitor.Enter(obj);
if (readflag == false)
Monitor.Wait(obj);
Console.WriteLine("Reader{0}", context);
readflag = false;
Monitor.Pulse(obj);
Monitor.Exit(obj);
}
public class Writer
{
private Resource rec;
public Writer(Resource r)
{
rec = r;
}
public void Run()
{
for (int i = 0; i < 10; i++)
rec.Write();
}
}
public class Reader
{
private Resource rec;
public Reader(Resource r)
{
rec = r;
}
public void Run()
{
for (int i = 0; i < 10; i++)
rec.Read();
}
}
class Program
{
static void Main(string[] args)
{
Resource r = new Resource();
Writer writer = new Writer(r);
Reader reader = new Reader(r);
Thread wThread = new Thread(writer.Run);
Thread rThread = new Thread(reader.Run);
wThread.Start();
rThread.Start();
}
}
}
}
//
Writer:1
Reader1
Writer:2
Reader2
Writer:3
Reader3
Writer:4
Reader4
Writer:5
Reader5
Writer:6
Reader6
Writer:7
Reader7
Writer:8
Reader8
Writer:9
Reader9
Writer:10
Reader10