您的位置:首页 > 编程语言 > C#

C# 语言的多线程编程,完全是本科OS里的知识

2014-10-11 17:30 344 查看

基本知识,无参数Thread和带参数的Thread

Thread类的参数就是参数指针,可以传入一个无参的函数。

如果要传入带参数的函数,先new一个ParameterizedThreadStart委托实例,带参数的函数名作为它的参数。带参数的函数必须且只能有一个object参数。参考下面的

ConterWithParam(object param)

static int iCnt = 0;
static readonly int N = 10000;

static void Main(string[] args)
{
Thread[] thrs = new Thread
;
for (int i = 0; i < N; i++)
{
thrs[i] = new Thread(Counter);
thrs[i].Start();
}
for (int i = 0; i < N; i++)
{
thrs[i].Join();
}
Console.WriteLine(iCnt);

iCnt = 0;

ParameterizedThreadStart[] thrsp = new ParameterizedThreadStart
;
object param = 2;
for (int i = 0; i < N; i++)
{
thrsp[i] = new ParameterizedThreadStart(ConterWithParam);
thrs[i] = new Thread(thrsp[i]);
thrs[i].Start(param);
}
for (int i = 0; i < N; i++)
{
//当NewThread调用Join方法的时候,MainThread就被停止执行,直到NewThread线程执行完毕
thrs[i].Join();
}
Console.WriteLine(iCnt);
}

static void Counter()
{
Thread.Sleep(100);
iCnt++;
//Console.WriteLine("finish iCnt++,now iCnt is " + iCnt);
}

static void ConterWithParam(object param)
{
Thread.Sleep(100);
int i = (int)param;
iCnt += i;
//Console.WriteLine("finish iCnt+"+i+",now iCnt is " + iCnt);
}


该例子输出结果



2)互斥信号灯mutex

第一节的结果是不是有点奇怪。明明加了10000次,结果却是9550.

带参数的那个例子,一次加2,加10000次,应该是20000才对。结果却是19678.

这是因为对全局变量的访问iCnt出现了冲突。比如两个线程同时取到了iCnt=0时的值,同时执行了i++,那么iCnt的最后状态肯定是1,而不是会2。为了让iCnt得到正确的值。

我们引入互斥信号灯。

static int iCnt = 0;
static readonly int N = 10000;
static Mutex mut = new Mutex();

static void Main(string[] args)
{
Thread[] thrs = new Thread
;
for (int i = 0; i < N; i++)
{
thrs[i] = new Thread(Counter);
thrs[i].Start();
}
for (int i = 0; i < N; i++)
{
thrs[i].Join();
}
Console.WriteLine(iCnt);

iCnt = 0;

ParameterizedThreadStart[] thrsp = new ParameterizedThreadStart
;
object param = 2;
for (int i = 0; i < N; i++)
{
thrsp[i] = new ParameterizedThreadStart(ConterWithParam);
thrs[i] = new Thread(thrsp[i]);
thrs[i].Start(param);
}
for (int i = 0; i < N; i++)
{
//当NewThread调用Join方法的时候,MainThread就被停止执行,直到NewThread线程执行完毕
thrs[i].Join();
}
Console.WriteLine(iCnt);
}

static void Counter()
{
Thread.Sleep(10);
//锁
mut.WaitOne();
iCnt++;
//释放
mut.ReleaseMutex();
//Console.WriteLine("finish iCnt++,now iCnt is " + iCnt);
}

static void ConterWithParam(object param)
{
Thread.Sleep(10);
//锁住
mut.WaitOne();
int i = (int)param;
iCnt += i;
//释放
mut.ReleaseMutex();
//Console.WriteLine("finish iCnt+"+i+",now iCnt is " + iCnt);
}


本次执行结果



3) 同步信号灯Semaphore

用最经典的生产者-消费者来解释。

static Semaphore sem = new Semaphore(0, 1);
static Semaphore sem2 = new Semaphore(0, 5);

static void Main(string[] args)
{
Console.WriteLine("消费者等生产者生产一个item");
Thread thConsumer = new Thread(Consume);
thConsumer.Start();
Thread thProductor = new Thread(Product);
thProductor.Start();

thConsumer.Join();
thProductor.Join();
Console.WriteLine(".............................");

Console.WriteLine("多并发的例子.....");
for (int i = 0; i < 10; i++)
{
Thread t1 = new Thread(Consume2);
t1.Start();
Thread t2 = new Thread(Product2);
t2.Start();
}//end for

}

static void Product()
{
Thread.Sleep(2000);
Console.WriteLine("Product an item...");
sem.Release();
}

static void Consume()
{
Thread.Sleep(1000);
Console.WriteLine("Consumer is waiting an item...");
sem.WaitOne();
Console.WriteLine("Consumer get an item...");
}

static void Product2()
{
Thread.Sleep(1000);
Console.WriteLine("Product an item...");
sem2.Release();
}

static void Consume2()
{
Thread.Sleep(1000);
Console.WriteLine("Consumer is waiting an item...");
sem2.WaitOne();
Console.WriteLine("Consumer get an item...");
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: