中断本机线程
我目前正在研究 Thread.Interrupt 如何与 P/Invoke 或本机调用一起使用。我在 MSDN 中读到,不可能中止(Thread.Abort)本机调用中的线程(其他用例也可能适用)。但我没有找到任何对处于 WaitSleepJoin 状态的本机线程进行相同说明的参考。
这个问题不是关于是否应该调用中止或中断,而是关于我在哪里可以找到这方面的权威文档。 G-ing 没有提供任何有用的输出。
我的测试示例:
#ifdef NATIVEFUNCTIONS_EXPORTS
#define NATIVEFUNCTIONS_API __declspec(dllexport)
#else
#define NATIVEFUNCTIONS_API __declspec(dllimport)
#endif
#include <iostream>
extern "C"
{
NATIVEFUNCTIONS_API void EndlessWait(char const* mutexName)
{
std::cout << "entering the endless wait." << std::endl;
HANDLE mutex = CreateMutex(NULL, FALSE, mutexName);
WaitForSingleObject(mutex, INFINITE);
std::cout << "leaving the endless wait." << std::endl;
}
};
本机 C++-DLL,它导出一个函数,该函数无休止地等待互斥体。
现在,C# .NET 对应项尝试取消等待:
using System;
using System.Threading;
using System.Runtime.InteropServices;
namespace InterruptingNativeWaitingThread
{
class Program
{
[DllImport("NativeFunctions.dll", CharSet=CharSet.Ansi)]
static extern void EndlessWait(string str);
static void Main(string[] args)
{
string mutexName = "interprocess_mutex";
Mutex m = new Mutex(false, mutexName);
m.WaitOne();
Thread t = new Thread(() => { EndlessWait(mutexName); });
t.Start();
Thread.Sleep(1000);
t.Abort();
if(!t.Join(5000))
Console.WriteLine("Unable to terminate native thread.");
t.Interrupt();
if(!t.Join(5000))
Console.WriteLine("Unable to interrupt the native wait.");
Console.WriteLine("Release the mutex.");
m.ReleaseMutex();
t.Join();
}
}
}
执行此应用程序会产生以下输出:
entering the endless wait.
Unable to terminate native thread.
Unable to interrupt the native wait.
Release the mutex.
leaving the endless wait.
Abort 在此上下文中无法按预期工作,但 msdn 没有提及任何有关中断的信息。我希望它一方面可以工作:因为处于等待状态的托管线程也会调用本机 WaitForSingleObject 或 WaitForMultipleObjects;另一方面,有可能被中断的本机线程不支持全部期望异常,那又如何呢?
任何医生都非常欢迎!
非常感谢,
奥瓦内斯
我还在 MSDN 中发现 abort 会等到线程被中止如果线程处于 WaitSleepJoin 状态,则从非托管代码返回并首先调用中断,然后中止它。但这并不意味着中断不能中断本机WaitSleepJoin。
I am currently investigating how Thread.Interrupt plays together with P/Invoke or native calls. I have read in MSDN that it is not possible to abort (Thread.Abort) a thread which is in the native call (other use cases might apply as well). But I did not find any reference which states the same for native threads which are in WaitSleepJoin state.
This question is not about whether one should call Abort or Interrupt, but about where I can find authorative doc on this. G-ing for this did not provide any useful output.
My test example:
#ifdef NATIVEFUNCTIONS_EXPORTS
#define NATIVEFUNCTIONS_API __declspec(dllexport)
#else
#define NATIVEFUNCTIONS_API __declspec(dllimport)
#endif
#include <iostream>
extern "C"
{
NATIVEFUNCTIONS_API void EndlessWait(char const* mutexName)
{
std::cout << "entering the endless wait." << std::endl;
HANDLE mutex = CreateMutex(NULL, FALSE, mutexName);
WaitForSingleObject(mutex, INFINITE);
std::cout << "leaving the endless wait." << std::endl;
}
};
Native C++-DLL which exports a function, that endlessly waits on a mutex.
Now the C# .NET counterpart, which tries to cancel the wait:
using System;
using System.Threading;
using System.Runtime.InteropServices;
namespace InterruptingNativeWaitingThread
{
class Program
{
[DllImport("NativeFunctions.dll", CharSet=CharSet.Ansi)]
static extern void EndlessWait(string str);
static void Main(string[] args)
{
string mutexName = "interprocess_mutex";
Mutex m = new Mutex(false, mutexName);
m.WaitOne();
Thread t = new Thread(() => { EndlessWait(mutexName); });
t.Start();
Thread.Sleep(1000);
t.Abort();
if(!t.Join(5000))
Console.WriteLine("Unable to terminate native thread.");
t.Interrupt();
if(!t.Join(5000))
Console.WriteLine("Unable to interrupt the native wait.");
Console.WriteLine("Release the mutex.");
m.ReleaseMutex();
t.Join();
}
}
}
Executing this app produces the following output:
entering the endless wait.
Unable to terminate native thread.
Unable to interrupt the native wait.
Release the mutex.
leaving the endless wait.
Abort does not work in this context as expected, but msdn does not say a word about interrupt. I would expect it work on one hand: since the managed thread being in Wait state also calls the native WaitForSingleObject or WaitForMultipleObjects; on the other hand, there is a possibility that native thread to be interrupted does not support expect exceptions all, what than?
Any doc is very welcome!
Many thanks,
Ovanes
P.S. I also found in MSDN that abort waits until the thread to be aborted returns from the unmanaged code and first call interrupt if the thread is in WaitSleepJoin state and than aborts it. But that does not mean that interrupt can't interrupt native WaitSleepJoin.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我怀疑线程处于WaitSleepJoin状态;中断被记录为仅中断处于此状态的线程。查看线程的 ThreadState 属性以验证其处于什么状态。
I doubt that the thread is in the WaitSleepJoin state; Interrupt is documented to only interrupt threads in this state. Look at the ThreadState property of the thread to verify what state it is in.