如何实现像lock语句中那样的互斥,但是如果块被锁定就会被跳过?

发布于 2024-12-23 03:42:15 字数 413 浏览 2 评论 0原文

使用lock语句,可以“确保一个线程不进入当另一个线程位于代码的关键部分时,如果另一个线程尝试输入锁定的代码,它将等待、阻塞,直到对象被释放。”

如果我想要的行为是如果另一个线程尝试输入锁定的代码,它将跳过整个代码(而不是等待锁被释放)怎么办?我想到的一个想法是使用一个标志,比如

if(flag) return;
flag = true;
//do stuff here
flag =false;

但我知道这不安全,因为两个线程可以在任何人设置为 true 之前传递第一行,或者在出现异常的情况下标志永远不会设置为 false ..可以您建议改进或替代方案吗?

Using the lock statement, one can "ensure that one thread does not enter a critical section of code while another thread is in the critical section. If another thread tries to enter a locked code, it will wait, block, until the object is released."

What if the behaviour I want is that if another thread tries to enter the locked code, it will just skip the whole code (instead of waiting the lock to be released)? An idea that come to my mind is using a flag, something like

if(flag) return;
flag = true;
//do stuff here
flag =false;

But I know this is not safe because two threads can pass the first line before anyone set to true, or the flag being never set to false in case of exceptions.. Can you suggest an improvement or an alternative?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

茶底世界 2024-12-30 03:42:15

使用 Monitor.TryEnter此重载,它允许您指定超时。

在指定的时间内尝试获取独占
锁定指定对象。

返回值类型:System.Boolean 如果当前线程获取则为 true
锁无阻塞;否则为假。

在您的情况下,您可能希望使用接近 TimeSpan.Zero 的超时。

如果您不希望尝试获取锁的线程等待任何时间,您可以Monitor.TryEnter 的此重载,它不接受 TimeSpan 参数。此方法将立即返回,无需等待 - 非常接近您尝试使用的标记技术的情绪。

Use this overload of Monitor.TryEnter, which lets you specify a timeout.

Attempts, for the specified amount of time, to acquire an exclusive
lock on the specified object.

Return Value Type: System.Boolean true if the current thread acquires
the lock without blocking; otherwise, false.

In your case, you probably want to use a timeout of close to TimeSpan.Zero.

If you don't want the thread attempting to take the lock to wait for any length of time, you can just this overload of Monitor.TryEnter, which does not accept a TimeSpan argument. This method will immediately return without waiting - very close to the sentiment of the flag technique you are trying to use.

清欢 2024-12-30 03:42:15

您需要限制为 1 且超时时间为 0 的 信号量毫秒

通过使用信号量,您可以说一次只有有限数量的线程可以访问一段代码。

请参阅此示例了解如何使用它

您需要使用该等待方法

bool WaitOne(int millisecondsTimeout)

指定超时时间=0;这样,您的等待线程将等待 0 秒,这意味着它们将简单地跳过代码

示例

class SemaphoreExample    
{ 
// Three reserved slots for threads
public static Semaphore Pool = new Semaphore(1, 0);

public static void Main(string[] args) 
{    
// Create and start 20 threads    
for (int i = 0; i < 20; i++) 
{ 
    Thread t = new Thread(new ThreadStart(DoWork)); 
    t.Start(); 
}

Console.ReadLine();    
}

private static void DoWork()    
{    
// Wait 0 miliseconds  
SemaphoreExample.Pool.WaitOne(0);


#region Area Protected By Semaphore    
Console.WriteLine("Acquired slot...");

for (int i = 0; i < 10; i++) 
{   
    Console.WriteLine(i + 1);  
}   
Console.WriteLine("Released slot...");    

#endregion        
// Release the semaphore slot    
SemaphoreExample.Pool.Release();    
}    
}

You need Semaphores with a limit 1 and timeout period 0 miliseconds

By using Semaphore you can say that only a limited number of threads can access a piece of code at a time.

See this sample for how to use it

You need to use this method for waiting

bool WaitOne(int millisecondsTimeout)

specify timeout period = 0; in this way your waiting threads will wait 0 second which means they will simply skip the code

Example

class SemaphoreExample    
{ 
// Three reserved slots for threads
public static Semaphore Pool = new Semaphore(1, 0);

public static void Main(string[] args) 
{    
// Create and start 20 threads    
for (int i = 0; i < 20; i++) 
{ 
    Thread t = new Thread(new ThreadStart(DoWork)); 
    t.Start(); 
}

Console.ReadLine();    
}

private static void DoWork()    
{    
// Wait 0 miliseconds  
SemaphoreExample.Pool.WaitOne(0);


#region Area Protected By Semaphore    
Console.WriteLine("Acquired slot...");

for (int i = 0; i < 10; i++) 
{   
    Console.WriteLine(i + 1);  
}   
Console.WriteLine("Released slot...");    

#endregion        
// Release the semaphore slot    
SemaphoreExample.Pool.Release();    
}    
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文