c#多线程编程笔记
[myElement]表示变量
第一部分 线程的概念
第二部分 线程的基本用法
第一步:引入命名空间:using System.Threading;
第二步:申明ThreadStart(即线程的入口);语法格式如下:
ThreadStart myThreadStart=new ThreadStart([method]);
第三步:定义一个线程;语法格式如下:
Thread [threadOne]=new Thread([ThreadStart]);
[ThreadStart]必须定义好!
第四步:执行线程,语法格式如下:
[Thread].Start();
其它语法:
挂起线程:表示处理器不再需要安排这个线程的执行。[workerThread].Suspend();
休眠进程:表示暂停[wokerThread].Sleep([time]);
联接线程:将使调用线程进入WaitSleepJoin状态,然后调用线程将阻塞,直到另一个线程实例终止。[worker].Join();
例子1:
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;//引入这个命名空间
namespace ConsoleApplication1
{
class Program1
{
static void main(string[] args)
{
Console.WriteLine(“{Main Thread} Creating the thread start delegate.”);
ThreadStart workerThreadStart = new ThreadStart(SimpleWorkerThread);//定义一//个线程入口为SimpleWorkerThread.
Console.WriteLine(“{Main Thread} Creating the worker thread.”);
Thread workerThread = new Thread(workerThreadStart);//定义一个线程,线程名为workerThread
//线程开始
workerThread.Start();
Console.Read();
//线程的非正常结束
workerThread.Abort();
Console.WriteLine(“{Main Thread} Aborting worker thread.”);
workerThread.Join();
Console.WriteLine(“{Main Thread} Worker Thread Terminated.”);
Console.Read();
}
public static void SimpleWorkerThread()
{
for (int i = 0; ; i++)
{
try
{
Console.WriteLine(“Hello from the worker thread.”);
if (i > 1000)
{
Thread.CurrentThread.Abort();
return;
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString()+” Exception caught.”);
Thread.ResetAbort();
}
}
}
}
}
第三部分 线程的同步
同步的意思是在多线程程序中,为了使两个或多个线程之间,对分配临界资源的分配问题,要如何分配才能使临界资源在为某一线程使用的时候,其它线程不能再使用,这样可以有效地避免死锁与脏数据。脏数据是指两个线程同时使用某一数据,造成这个数据出现不可预知的状态!在C#中,对线程同步的处理有如下几种方法:
a) 等待事件:当某一事件发生后,再发生另一件事。
例子3:
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace ConsoleApplication1
{
public class ClassCounter
{
protected int m_iCounter = 0;
public void Increment()
{
m_iCounter++;
}
public int Counter
{
get
{
return m_iCounter;
}
}
}
public class EventClass
{
protected ClassCounter m_protectedResource = new ClassCounter();
protected ManualResetEvent m_manualResetEvent = new ManualResetEvent(false);//ManualResetEvent(initialState),initialState如果为true,则将初始状态设置为终止;如果为false,则将初始状态设置为非终止。
protected void ThreadOneMethod()
{
m_manualResetEvent.WaitOne();//在这里是将入口为ThreadOneMethod的线程设为等待
m_protectedResource.Increment();
int iValue = m_protectedResource.Counter;
System.Console.WriteLine(“{Thread one} - Current value of counter:”+iValue.ToString());
}
protected void ThreadTwoMethod()
{
int iValue = m_protectedResource.Counter;
Console.WriteLine(“{Thread two}-current value of counter;”+iValue.ToString());
m_manualResetEvent.Set();//激活等待的线程
}
static void
Main
()
{
EventClass exampleClass = new EventClass();
Thread threadOne = new Thread(new ThreadStart(exampleClass.ThreadOneMethod));
Thread threadTwo = new Thread(new ThreadStart(exampleClass.ThreadTwoMethod));
threadOne.Start();//请注意这里,这里是先执行线程1
threadTwo.Start();//再执行线程2,那么线程2的值应该比线程1大,但结果相反
Console.ReadLine();
}
}
}
ManualResetEvent它允许线程之间互相发消息。
结果如下:
a) 使用Mutex类
Mutex是一个特殊的同步类,只能用来同步线程,不过Mutex可以跨进程对线程进行同步。Mutex类确保了一次只有一个线程可以访问同一资源。MSDN中的描述如下:” Mutex 是同步基元,它只向一个线程授予对共享资源的独占访问权。如果一个线程获取了互斥体,则要获取该互斥体的第二个线程将被挂起,直到第一个线程释放该互斥体。”对互斥体,MSDN有如下描述:”互斥体有两种类型:局部互斥体和已命名的系统互斥体。如果使用接受名称的构造函数创建 Mutex 对象,则该对象与具有该名称的操作系统对象关联。已命名的系统互斥体在整个操作系统中都可见,可用于同步进程活动。您可以创建多个 Mutex 对象来表示同一个已命名的系统互斥体,也可以使用 OpenExisting 方法打开现有的已命名系统互斥体。局部互斥体仅存在于您的进程内。您的进程中任何引用局部 Mutex 对象的线程都可以使用它。每个 Mutex 对象都是一个单独的局部互斥体。”
例子4:
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace ConsoleApplication1
{
class mutex4
{
private static Mutex mut=new Mutex();
private const int numIterations = 1;
private const int numTreads = 3;
static void
Main
()
{
Thread myThread = new Thread(new ThreadStart(MyThreadProc));
myThread.Name = “Thread”;
Thread myThread1 = new Thread(new ThreadStart(MyThreadProc));
myThread1.Name = “Thread1″