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即可
*/
719

被折叠的 条评论
为什么被折叠?



