2009-09-26 7 views
2

현재 P/Invoke 또는 네이티브 호출과 함께 Thread.Interrupt가 어떻게 재생되는지 조사 중입니다. 나는 MSDN에서 (Thread.Abort) 네이티브 호출에있는 스레드를 중단 할 수 없다는 것을 읽었습니다. 다른 사용 사례도 마찬가지로 적용될 수 있습니다. 하지만 WaitSleepJoin 상태에있는 원시 스레드에 대해 동일한 내용의 참조를 찾지 못했습니다.네이티브 스레드 인터럽트

이 질문은 Abort 또는 Interrupt를 호출해야하는지 여부에 관한 것이 아니라 여기에서 권한있는 문서를 찾을 수있는 위치에 관한 것입니다. 이를위한 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. 
예상대로 중단이 상황에서 작동하지 않습니다

, 그러나 msdn은 인터럽트에 대한 말을하지 않습니다. 한 손으로 작업 할 것이라고 기대합니다. 관리되는 스레드가 대기 상태이기 때문에 기본 WaitForSingleObject 또는 WaitForMultipleObjects도 호출합니다. 다른 한편으로 인터럽트 될 네이티브 스레드가 예외 예외를 모두 지원하지 않을 가능성이 있습니다.

모든 의사를 환영합니다!

많은 감사,
Ovanes

P.S. 또한 MSDN에서 스레드가 WaitSleepJoin 상태에 있고 중단 된 경우 중단 될 스레드가 관리되지 않는 코드에서 반환되고 처음 인터럽트를 호출 할 때까지 abort가 대기한다는 것을 발견했습니다. 하지만 인터럽트가 기본 WaitSleepJoin을 인터럽트 할 수 없다는 의미는 아닙니다.

답변

2

스레드가 WaitSleepJoin 상태에있는 것으로 의심됩니다. 인터럽트는이 상태의 스레드 만 인터럽트하도록 문서화됩니다. 스레드의 ThreadState 속성을보고 어떤 상태인지 확인하십시오.

+0

실제로 스레드는 실행 중 상태입니다. .NET처럼 자신의 스레드 상태 관리가 있습니다. t.Abort()에 대한 호출이있는 행 다음에 스레드는 AbortRequested 상태이지만 Thread.Interrupt는 WaitSleepJoin 상태가 아니기 때문에 스레드를 인터럽트하지 않습니다. 많은 감사합니다! – ovanes