【无标题】

多线程与异步C

1.线程是进程的一部分,一个进程包括多个进程,此处多个进程皆可以访问进程共享的资源
1.1 此处多次运算结果不同

        static void Main(string[] args)
        {

            const int total = 100000;

            int count = 0;

            var thread1 = new Thread(ThreadMethod);

            var thread2 = new Thread(ThreadMethod);

            thread1.Start();
            thread2.Start();
            thread1.Join();
            thread2.Join();

            Console.WriteLine($"Count{count}");

            Console.ReadLine();

            void ThreadMethod()
            {
                for (int i = 0; i < total; i++)
                {
                    count++;
                }
            }
        }
1.2	此处多次运算结果相同	
static void Main(string[] args)
{

    const int total = 100000;

    object v = new object();

    int count = 0;

    var thread1 = new Thread(ThreadMethod);

    var thread2 = new Thread(ThreadMethod);

    thread1.Start();
    thread2.Start();

    thread1.Join();
    thread2.Join();

    Console.WriteLine($"Count{count}");

    Console.ReadLine();


    void ThreadMethod()
    {
        for (int i = 0; i < total; i++)
        {
            lock (v) 
            count++;
        }
    }
}

2.为什么需要多线程
1、批量重复任务同时进行–对于数组的元素进行相同且耗时的计算
2、多个不同任务同事进行,互不干扰
3、WPF的UI线程与IO任务
3.什么事线程池–预先被创建,可以重复使用,一个线程的生命周期很耗时
4.异步变成默认使用线程池
5.线程安全问题:
5.1多个线程访问共享资源时,对资源的访问不同表格导致不可语预期的问题
5.2
method1:同步机制(互斥锁):协调控制多个线程之间执行顺序语互斥访问共享资源
确定 线程之间按照特定顺序执行避免竞争与条件不一致
static void Main(string[] args)

{

    const int total = 100000;

    object v = new object();

    int count = 0;

    var thread1 = new Thread(ThreadMethod);

    var thread2 = new Thread(ThreadMethod);

    thread1.Start();
    thread2.Start();

    thread1.Join();
    thread2.Join();

    Console.WriteLine($"Count{count}");

    Console.ReadLine();


    void ThreadMethod()
    {
        for (int i = 0; i < total; i++)
        {
            lock (v) 
            count++;
        }
    }
}
	method2:原子操作:执行过程中不会被中断 ---Interlocked
 static void Main(string[] args)
{
     
    const int total = 100000;

    //object v = new object();

    int count = 0;

    var thread1 = new Thread(ThreadMethod);

    var thread2 = new Thread(ThreadMethod);

    thread1.Start();
    thread2.Start();

    thread1.Join();
    thread2.Join();

    Console.WriteLine($"Count{count}");

    Console.ReadLine();


    void ThreadMethod()
    {
        for (int i = 0; i < total; i++)
        {
            Interlocked.Increment(ref count);
            //lock (v) 
            count++;
        }
    }
}

6.常用的实现方式
1.线程
2.线程池
3.异步编程— asysn await
4.自带方法(并行操作)-- parallel plinq
4.1对比 常规操作

var inputs = Enumerable.Range(1, 20).ToArray();

var outputs = new int[inputs.Length];

Stopwatch sw = Stopwatch.StartNew();

for (int i = 0; i < inputs.Length; i++) 
{
    outputs[i] = HeavyArray(inputs[i]);
}

Console.WriteLine($"Elaspsed time:{sw.ElapsedMilliseconds}ms");

PrintArray(outputs);

Console.ReadLine();

int HeavyArray(int input)
{
    Thread.Sleep(100);
    return input * input;
}

void PrintArray<T>(T[] array)
{
    for (int i = 0;i < array.Length; i++)
    {
        Console.WriteLine(array[i]);
    }
}
2080ms
4.2对比 并行操作--Parallel
```csharp
Parallel.For(0, inputs.Length, i =>
{
    outputs[i] = HeavyArray(inputs[i]);
});

`420ms

4.3对比 并行操作--PLinq
/// question1:在数据量较大的情况下,可能会导致顺序问题(将数组长度设置为1000也未导致)	
//解决方式outputs=inputs.AsParallel().AsOrdered().Select(x=>HeavyArray(x)).ToArray();

outputs=inputs.AsParallel().Select(x=>HeavyArray(x)).ToArray();

371ms

7 线程:
7.1:线程的创建
创建Thread实例,并传入ThreadStart委托–还可以配置线程(设置为后台线程)
前台线程:独立线程,后台线程:依附于前台线程(如main方法)
调用Thread.Start方法,还可以传参
在这里插入图片描述
7.2:线程的终止

Thread thread = new Thread((obj) =>
{
    Console.WriteLine(obj);
    for (int i = 0; i < 20; i++)
    {
        Thread.Sleep(200);
        Console.WriteLine("Thread is still runing ...");
    }
})
{ IsBackground = true,Priority = ThreadPriority.Normal};

thread.Start(123);
Console.WriteLine("In main thread,waiting for thread to finish");
thread.Join();
Console.WriteLine("Done.");
Console.ReadLine();

主线程会被阻塞

7.3:现成的挂起与恢复
Thread thread = new Thread((obj) =>
{
    try {
        Console.WriteLine(obj);
        for (int i = 0; i < 20; i++)
        {
            Thread.Sleep(200);
            Console.WriteLine("Thread is still runing ...");
        }
    } catch(ThreadInterruptedException ) 
    {

    }
    finally {
        Console.WriteLine("Thread is finishede");
        }
})
{ IsBackground = true, Priority = ThreadPriority.Normal };

thread.Start(123);
Console.WriteLine("In main thread,waiting for thread to finish");
Thread.Sleep(1000);
thread.Interrupt();
thread.Join();
Console.WriteLine("Done.");
Console.ReadLine();

此处仅运行4次

try {
    while (true)
    {

    }
    //Console.WriteLine(obj);
    //for (int i = 0; i < 20; i++)
    //{
    //    Thread.Sleep(200);
    //    Console.WriteLine("Thread is still runing ...");
    //}
} catch(ThreadInterruptedException ) 
{

}
finally {
    Console.WriteLine("Thread is finishede");
    }

这种情况下,thread不会interrupt 因为太忙了
此时

try {
    while (true)
    {
		 Thread.Sleep(0);
    }
    //Console.WriteLine(obj);
    //for (int i = 0; i < 20; i++)
    //{
    //    Thread.Sleep(200);
    //    Console.WriteLine("Thread is still runing ...");
    //}
} catch(ThreadInterruptedException ) 
{

}
finally {
    Console.WriteLine("Thread is finishede");
    }

即可 interrupt

8线程安全与同步机制
Thread—Safety
8.0锁与信号量
1.lock&Monitor
在这里插入图片描述

		2.Mutex -互斥锁
		3.SemapPhone -旗语?线程间的同步 线程间通信
//第一个3 初始化3个  第二个3 max3个
Semaphore semaphore = new Semaphore(3, 3,ThreadName?);

outputs = inputs.AsParallel().AsOrdered().Select(x => HeavyArray(x)).ToArray();

Console.WriteLine($"Elaspsed time:{sw.ElapsedMilliseconds}ms");

PrintArray(outputs);

//此处需要销毁掉
semaphore.Dispose();

Console.ReadLine();

int HeavyArray(int input)
{
    //等待信号量
    semaphore.WaitOne();
    Thread.Sleep(100);
    //释放信号量
    semaphore.Release();
    return input * input;
}

此时耗时会增加–避免并行过快
4.WaitHandle
4.1-- manualResetEvent
4.2–AutoResetEvent
5.ReadWriterLock --读写锁 只有一个writer在写
在这里插入图片描述

	8.1 轻量锁
		semaPhoneSlim  --存在异步版本
		ManuaReseEventSlim
		ReaderWriterLockSlim
	8.2 原子操作
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值