线程通信——锁与互斥锁

1.锁(Lock): 

//较常用简单例子多线程访问共享资源
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
​
namespace TestCode
{
    internal class Program
    {
        private static int _sourceId = 0;
        private static readonly object _lock=new object();
        static void Main(string[] args)
        {
            Thread t1 = new Thread(Process1);
            Thread t2 = new Thread(Process2);
​
            t1.Start();
            t2.Start();
​
            //t1.Join();
            //t2.Join();
            Console.WriteLine("task end");
            Console.ReadKey();
        }
        private static void Process1()
        {
            for (int i = 0; i < 10; i++)
            {
                Console.WriteLine($"执行任务ONE");
                lock (_lock)
                {
                    _sourceId++;
                }
                Console.WriteLine($"任务ONE sourceId:{_sourceId}");
                Thread.Sleep(100);
            }
        }
        private static void Process2()
        {
            for (int i = 0; i < 10; i++)
            {
                Console.WriteLine($"执行任务TWO");
                lock (_lock)
                {
                    _sourceId++;
                }
                Console.WriteLine($"任务TWO执行结束 sourceId:{_sourceId}");
                Thread.Sleep(100);
            }
        }
    }
}
​

2.互斥锁(Mutex)

2.1互斥锁的介绍及与锁的区别

  • 介绍

    互斥锁通过控制多个线程在任何时刻只有一个线程拥有互斥锁,从而实现共享资源的访问。它分为命名与非命名的,命名的互斥锁用于夸进程共享,非命名互斥锁通常用于统一进程的不同线程之间。不同线程在获取互斥锁时若该锁未释放,该进程则处于等待状态,使用该锁的线程手动释放之后,等待的线程才能进行访问使用。

  • 与锁的区别
    • 作用范围

      • 互斥锁可以跨进程使用,适用于需要在不同应用程序之间同步的情况.

      • 仅在同一进程内的线程之间有效,适用于同一应用程序内的线程同步.

    • 使用方式

      • 互斥锁需要显式创建和释放,使用起来相对复杂一些.

      • 通过lock关键字实现,使用起来更简单直接.

    • 性能

      • 互斥锁由于可以跨进程使用,通常比锁的性能稍差一些,因为需要进行更多的系统调用和内核操作.

      • 在大多数情况下性能较好,因为其操作主要在用户态进行,不需要频繁的上下文切换.

    • 适用场景

      • 互斥锁适用于需要跨进程同步的场景,例如多个应用程序需要共享同一资源时.

      • 适用于同一应用程序内的线程同步,是大多数多线程程序的首选同步机制.

  • 总结

    同一个程序中多线程访问竞争资源,使用锁即可,需要用到跨进程共享竞争资源时再用互斥锁,因为其涉及到跨进程同步,开销更大。

2.2使用互斥锁进行跨进程通信


---------------------------(第一个控制台程序)
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
​
namespace TestCode
{
    internal class Program
    {
        private static int _sourceId = 0;
        private static readonly object _lock = new object();
        static void Main(string[] args)
        {
            TestMutex();
            Console.ReadKey();
        }
​
        #region 互斥锁跨进程使用
​
        private static void TestMutex()
        {
            //创建命名互斥锁
            using (Mutex mutex = new Mutex(false, "TestMutex"))
            {
                Console.WriteLine("process 1: Waiting for the mutex...");
​
                //记录开始时间
                Stopwatch stopwatch = Stopwatch.StartNew();
                // 请求互斥锁
                mutex.WaitOne();
                stopwatch.Stop();
                Console.WriteLine($"process1: Acquired the mutex in {stopwatch.ElapsedMilliseconds} ms.");
                try
                {
                    Console.WriteLine("Process 1: Acquired the mutex. Press Enter to release it.");
                    var input = Console.ReadLine(); // 模拟占用锁
                    Console.WriteLine($"Process 1 inpute:{input}");
                }
                finally
                {
                    // 释放互斥锁
                    mutex.ReleaseMutex();
                    Console.WriteLine("Process 1: Released the mutex.");
                }
            }
        }
        #endregion
    }
}
------------------------------------------------------------(第二个控制台程序)
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
​
namespace TestCode
{
    internal class Program
    {
        private static int _sourceId = 0;
        private static readonly object _lock = new object();
        static void Main(string[] args)
        {
            TestMutex();
            Console.ReadKey();
        }
​
        #region 互斥锁跨进程使用
​
        private static void TestMutex()
        {
            //创建命名互斥锁
            using (Mutex mutex = new Mutex(false, "TestMutex"))
            {
                Console.WriteLine("process 2: Waiting for the mutex...");
​
                //记录开始时间
                Stopwatch stopwatch = Stopwatch.StartNew();
                // 请求互斥锁
                mutex.WaitOne();
                stopwatch.Stop();
                Console.WriteLine($"process2: Acquired the mutex in {stopwatch.ElapsedMilliseconds} ms.");
                try
                {
                    Console.WriteLine("Process 2: Acquired the mutex. Press Enter to release it.");
                    var input = Console.ReadLine(); // 模拟占用锁
                    Console.WriteLine($"Process 2 inpute:{input}");
                }
                finally
                {
                    // 释放互斥锁
                    mutex.ReleaseMutex();
                    Console.WriteLine("Process 2: Released the mutex.");
                }
            }
        }
        #endregion
    }
}
/*
调试时分别运行exe即可
*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值