进程是系统进行资源分配和调度的一个独立单位。每一个用户进程拥有自己私有的地址空间,也就是说,进程拥有一定的可被其访问的内存区域。一个用户进程不可以直接访问其他进程的地址空间
线程是进程的执行单元,每一个进程中最少有一个线程。也可以有多个线程。线程共享进程中的资源,但是也有属于自己的(如程序计数器,一组寄存器和栈)等必需资源。
在DotNet中创建一个线程非常容易,首先你需要引入一个命名空间
using System.Thread;
然后你可以直接实例化一个线程类来,在调用这个线程类的Start方法,这个线程就被创建并运行了。
Thread t = new Thread();
t.Start();
当然你运行一个线程当然是有目的的,比如进行一个计算,进行一个操作等。那么你就将这些操作封装
成一个方法,然后将方法传递给线程的构造方法就好了
比如有一个方法
{
static void execute1()
{
Console.WriteLine("线程执行了");
}
static void Main(string args[])
{
Thread t = new Thread(execute1);
t.Start();
}
}
这样一个简单的线程就创建好了。但是他并没有任何意义,只是一个演示作用。
(下面记录自己的心得,有机会有时间真希望写一篇入门的教程)
线程同步的问题
1.Monitor对象与lock语句
Monitor对象,监视器对象
如果你有一段代码,希望一个时间点内只充许一个线程访问,看看如何限制
Monitor.Enter(this);//进入这段代码
//执行一段代码
Monitor.Exit(this);//执行完成后退出代码
基本线程安全的原因,下面是一段完整的演示代码
{
private Object locker = new Object();
static void Main(string args[])
{
Thread t1 = new Thread(exe1);
t1.Start();
Thread t2 = new Thread(exe1);
t2.Start();
}
static void exe1()
{
Monitor.Enter(locker);
Console.WriteLine("测试代码!");
Monitor.Exit(locker);
}
}
上面的代码完全没考虑到异常等情况,,
为了简化上述语句,MS引入了lock关键字,,他会自动为上述代码创建异常处理等代码。
使用lock后的代码如下
static void exe1()
{
lock(locker)
{
Console.WrilteLine("测试代码");
}
}
上面这些都是只能控制同一进程中的不同线程的同步,如果是不同的进程呢??可以采用下面的
Mutex 与 Semaphore
Muex是一个互斥像对象,可以象上面的一样同步不同进程中的线程。
Mutex mutex = new Mutex (false, "myMutex")
这样就创实例他一个名字叫"myMutex"的实例变量mutex,其中重点是这个实例变量可不是局部的
他是全局的,在不同的进程中是共享的,只要你的名字是相同的。注意,互斥量如果定义在方法中
下面不引用他,会被垃圾回收器回收掉。
进程1
线程中
Mutex mutex = new Mutex (false, "myMutex")
mutex.WaitOne();//这里就让线程去申请这个互斥量的使用权。如果该互斥量正在被使有,则该线程挂起
mutext.ReleaseMutex(); //使用完了,释放该互斥量。
进程2
线程中
Mutex mutex = new Mutex (false, "myMutex") //这里保证名称和进程1中一样。
mutex.WaitOne();//这里就让线程去申请这个互斥量的使用权。如果该互斥量正在被使有,则该线程挂起
mutext.ReleaseMutex(); //使用完了,释放该互斥量。
Semaphore
Semaphore 的特性与Mutex 和 lock有点类似,除了Semaphore没有“所有者”——它是不可知线程的,任何在Semaphore内的线程都可以调用Release,而Mutex 和 lock仅有那些获取了资源的线程才可以释放它。
在下面的例子中,10个线程执行一个循环,在中间使用Sleep语句。Semaphore确保每次只有不超过3个线程可以执行Sleep语句:
class SemaphoreTest {
//static Semaphore s = new Semaphore (3, 3); 这里忘记指定名字,则会生成 一个匿名的信吃量
static Semaphore s = new Semaphore(3,3,"MySemaphore");//创建一个有名字的信号量,所有进程都可以用
static void Main() {
for (int i = 0; i < 10; i++) new Thread (Go).Start();
}
static void Go() {
while (true) {
s.WaitOne();
Thread.Sleep (100); // 每次只有3个线程可以到达这里
s.Release();
}
}
}