2014-05-19 7 views
5

मैं अपने सी ++ कोड में काम करने के लिए APC प्राप्त करने का प्रयास कर रहा हूं लेकिन मैं असफल हूं। मैं शब्दों के लिए खो गया हूँ। सी # में यह सब ठीक काम करता है (तार्किक रूप से एक ही कोड)। मैं थ्रेड 2 को कॉल 1 में इंजेक्ट करने के लिए चाहता हूं। लेकिन मेरे सी ++ प्रोजेक्ट में यह किसी कारण से निष्पादित नहीं होगा। मैं क्या गलत कर रहा हूं ?असीमित प्रक्रिया कॉल

  • धागा 1 (मुख्य थ्रेड)
  • धागा 2 (उप धागा, कि एक समारोह निष्पादित करने के लिए मुख्य थ्रेड की जरूरत है)


कोड:

#include "stdio.h" 
#include "windows.h" 

#define TIME 2500 
#define LAST_ERROR printf("last error: %i\r\n", GetLastError()); 

HANDLE handle1, handle2; 

void ThreadInfo(char* prefix = "") 
{ 
    printf("%sthread id: %i\r\n", prefix, GetCurrentThreadId()); 
} 

VOID CALLBACK apc(_In_ ULONG_PTR data) 
{ 
    ThreadInfo(" -> apc: 2 -> 1: "); 
} 

void run1() 
{ 
    while (true) 
    { 
     Sleep(TIME); 
     ThreadInfo("1: "); 

     // apc 
     //QueueUserAPC(apc, handle2, (ULONG_PTR) NULL); 
    } 
} 

void run2() 
{ 
    while (true) 
    { 
     Sleep(TIME); 
     ThreadInfo("2: "); 

     // apc 
     QueueUserAPC(apc, handle1, (ULONG_PTR) NULL); 
    } 
} 

void TestThreads() 
{ 
    DWORD threadId; 
    SECURITY_ATTRIBUTES a; 
    a.nLength = 12; 
    a.lpSecurityDescriptor = NULL; 
    a.bInheritHandle = 1; 

    DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), GetCurrentProcess(), &handle1, 0, true, 2); 
    LAST_ERROR 

    handle2 = CreateThread(NULL, 100000, (LPTHREAD_START_ROUTINE)run2, NULL, 0, &threadId); 
    printf("handles (1, 2): %i, %i\r\n", handle1, handle2); 
    printf("ids (1, 2): %i, %i\r\n", threadId, GetCurrentThreadId()); 
    printf("--------------------------------\r\n"); 
    run1(); 
} 

int main() 
{ 
    TestThreads(); 

    printf("done."); 
    getchar(); 
    return 0; 
} 

उत्तर

9
Sleep(TIME); 

यह आपकी समस्या है ईएनटी। एपीसी बहुत खतरनाक हैं, वे कोड पुन: प्रवेश की अनुमति देते हैं। कुख्यात अनुप्रयोग के लिए बराबर समकक्ष। DoEvents() कथन जिसमें मुसीबत में इतने सारे वीबी प्रोग्रामर हैं। विंडोज़ उन्हें सिर्फ चलाने की अनुमति नहीं देता है, आपको स्पष्ट होना चाहिए कि आपका कोड पुनः दर्ज किया गया है ताकि एपीसी सुरक्षित रूप से आपके प्रोग्राम स्थिति को खराब किए बिना चला सके।

विशिष्ट आवश्यकता यह है कि आपका धागा "सतर्क प्रतीक्षा स्थिति" में है। प्रतीक्षा राज्य में जाना मुद्दा नहीं है, नींद() कॉल वह करता है। हालांकि यह एक सतर्क राज्य नहीं है। इसके बजाय आप इस का उपयोग करने के लिए है:

SleepEx(TIME, TRUE); 

अपने परीक्षण कार्यक्रम में संशोधित run1() फ़ंक्शन और तो अब आप देखेंगे एपीसी कॉलबैक कहा जाता हो रही है। GetOverlappedResultEx(), SignalObjectAndWait(), WaitForSingleObjectEx() और WaitForMultipleObjectsEx(), अन्य winapi कॉल से तुलना करें जो एक अलर्ट योग्य चेतावनी स्थिति में थ्रेड डाल सकता है। और हाँ, थ्रेड। स्लीप() एक प्रबंधित प्रोग्राम में सतर्क है, सीएलआर हुड के नीचे स्लीपएक्स() को कॉल करता है।

+0

आप घंटों पहले कहाँ गए हैं? :) मैं ** कभी नहीं सोचा होगा कि यह अनुमान लगाया जा रहा है 'नींद'। – Bitterblue

+2

मैं एस्लीपेक्स था :) आपके रेपो कोड पर मेरी प्रशंसा, इच्छा है कि प्रत्येक SO उपयोगकर्ता उन्हें आपकी मदद करने में आसान बना देगा। –

+0

[इस] के अनुसार (http://stackoverflow.com/a/3783845/1442225) एपीसी कॉल स्वीकार करने के लिए _healthy_ GUI थ्रेड बनाने का कोई तरीका नहीं होगा, है ना? मुझे इसे अब एमएफसी में उपयोग करना है। – Bitterblue

संबंधित मुद्दे