垃圾回收站

August 8, 2007

c#多线程编程笔记

[ 分类: .NET ] 由 弗里曼·潘 发表于 8:31 pm

[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″