一旦加入互斥锁,如何向线程发出信号以停止等待该互斥锁?

发布于 2024-10-01 08:51:38 字数 687 浏览 6 评论 0原文

我注意到我的一些服务挂起而不是按照指示关闭,因为它们正在等待其他服务持有的锁,而这些服务正在等待它们关闭(导致死锁)。为此,我需要某种方法来向等待锁关闭的线程发出信号,因此我想出了这个:

public static Boolean Lock(this Mutex mutex)
{
 Boolean achieved = false;

 while (Thread.CurrentThread.ThreadState != System.Threading.ThreadState.StopRequested)
 {
  try
  {
   achieved = mutex.WaitOne(TimeSpan.FromSeconds(10.0));
  }
  catch (AbandonedMutexException exception)
  {
   // Log this
  }
 }

 return achieved;
}

当每个服务停止时,它会在每个线程上调用 Join 。问题是,即使在调用 Thread 之后,ThreadState 仍然设置为 Running。最终,Join 将超时并且线程将中止,但我不希望事情发展到这种程度。

所以我有两个问题:

  1. 是否有某种方法让线程知道它已被加入(从而可以停止等待)?

  2. 有没有比我在这里提出的更好的方法来解决这个问题?

I noticed that some of my services were hanging instead of shutting down, as instructed, because they were waiting on locks held by other services that are waiting for them to shut down (causing a deadlock). To that end, I needed some way to signal the threads waiting for the lock to shut down, so I came up with this:

public static Boolean Lock(this Mutex mutex)
{
 Boolean achieved = false;

 while (Thread.CurrentThread.ThreadState != System.Threading.ThreadState.StopRequested)
 {
  try
  {
   achieved = mutex.WaitOne(TimeSpan.FromSeconds(10.0));
  }
  catch (AbandonedMutexException exception)
  {
   // Log this
  }
 }

 return achieved;
}

When each service is stopped, it calls Join on each of its threads. The problem is that the even after Thread has been called, the ThreadState is still set to Running. Eventually, the Join will timeout and the thread will be aborted, but I'd rather it not come to that.

So I have two questions:

  1. Is there some way for the thread to know that it's been joined (and thus can stop waiting)?

  2. Is there a better way to solve this problem than what I've come up with here?

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

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

发布评论

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

评论(2

我最亲爱的 2024-10-08 08:51:38

创建一个全局手动重置事件,在加入线程之前在服务关闭时将其设置,并在 Lock 函数中使用 WaitHandle.WaitAny (mutex, stopEvent)

internal static EventWaitHandle s_stopEvent ;

// in service startup code:
s_stopEvent = new ManualResetEvent (false) ;

public static void Stop (this IEnumerable<Thread> threads)
{
  s_stopEvent.Set () ;
  foreach (var thread in threads)
    thread.Join () ;
}

public static bool Lock (this Mutex mutex)
{
  try
  {
    return WaitHandle.WaitAny (new WaitHandle[] { mutex, s_stopEvent }) == 0 ;
  }
  catch (AbandonedMutexException exception)
  {
    // Log this
  }
}

Create a global manual-reset event, set it at service shutdown before joining your threads and use WaitHandle.WaitAny (mutex, stopEvent) in your Lock function:

internal static EventWaitHandle s_stopEvent ;

// in service startup code:
s_stopEvent = new ManualResetEvent (false) ;

public static void Stop (this IEnumerable<Thread> threads)
{
  s_stopEvent.Set () ;
  foreach (var thread in threads)
    thread.Join () ;
}

public static bool Lock (this Mutex mutex)
{
  try
  {
    return WaitHandle.WaitAny (new WaitHandle[] { mutex, s_stopEvent }) == 0 ;
  }
  catch (AbandonedMutexException exception)
  {
    // Log this
  }
}
不知在何时 2024-10-08 08:51:38

您必须在线程运行的任务中构建取消机制,因此除了取消之外,没有任何线程机制可以提供帮助。

看看这里:

http://www.albahari.com/threading/part3.aspx# _Cancellation_Tokens

You have to build cancellation mechanism into the task that your threads are running, so no threading mechanism - apart from cancellation - can help.

Have a look here:

http://www.albahari.com/threading/part3.aspx#_Cancellation_Tokens

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