2012-06-27 18 views
6

Tôi đã tạo chuỗi bằng chức năng "CreateThread".Windows C++ - đóng chuỗi bằng CloseHandle

trong chủ đề này, tôi có vòng lặp 'while (true)' (đọc đầu vào).

hiện tại, khi tôi muốn đóng chuỗi, tôi sử dụng chức năng 'CloseHandle'.

Đây có phải là điều đúng để làm không? Hoặc tôi nên thoát khỏi vòng lặp 'while (true)' và sau đó sử dụng chức năng 'CloseHandle'?

Cảm ơn

Trả lời

8

CloseHandle() không phá hủy, chấm dứt hoặc ngắt kết nối luồng, nó chỉ phá hủy tay cầm (vì vậy bạn không có tay cầm để hủy chỉ hoặc đợi). Các chủ đề vẫn tiếp tục làm việc bình thường (tôi đã sử dụng điều này trong nhiều trường hợp), và cách duy nhất để ngăn chặn nó hoặc là thoát khỏi chức năng thread (ThreadProc()), hoặc giết nó.

6

chung này (gọi TerminateThread) là một điều xấu để làm vì một sợi có thể phân bổ một số tài nguyên (ví dụ: file descriptor) mà sẽ không có sẵn cho đến khi toàn bộ quá trình chấm dứt. Thậm chí nhiều hơn, các CloseHandle không dừng thread.

Nếu bạn có một số hoạt động dài bên thread của bạn, sau đó sử dụng ít nhất chu kỳ

while(!ShouldExit) 
{ 
    DoOneMoreIteration(); 
} 

. Bằng cách này bạn có thể chấm dứt thread bằng cách thiết lập ShouldExit thành 1 (hoặc 'true', nếu nó là C++ và bool variable) và WaitForSingleObject gọi trên handle của thread này để đảm bảo nó đã kết thúc.

Đối với nhận xét của eran: Giá trị phải được khai báo là 'dễ bay hơi'.

Nếu bạn đang đợi một số đầu vào (bảng điều khiển tôi giả sử), thì bạn có thể sử dụng I/O không chặn ("chồng chéo") với đầu vào tiêu chuẩn.

Ví dụ: xem câu hỏi này: Checking Win32 file streams for available input

Nó sẽ là một cái gì đó giống như

HANDLE h = GetStdHandle(STD_INPUT_HANDLE); 

while(!ShouldExit) { 
    if(WaitForSingleObject(h, FALSE, SomeTimeoutValue) == WAIT_OBJECT_0) 
    { 
     ... use std::cin - it has some input and won't block 
    } 
} 

Để làm cho mọi việc tốt hơn (tránh CPU quá tải) sử dụng WaitForMultipleObjects và phá vỡ bên ngoài vòng lặp trên một số sự kiện bên ngoài.

/// Global var 
HANDLE SomeGlobalEvent; 

/// ThreadProc(): 
HANDLE h[2]; 
h[0] = GetStdHandle(STD_INPUT_HANDLE); 
h[1] = SomeGlobalEvent; 

while(true) { 
    DWORD which = WaitForMultipleObjects(2, h, FALSE, SomeTimeoutValue); 
    if(which == WAIT_OBJECT_0) 
    { 
     ... use std::cin - it has some input and won't block 
    } else 
    if(which == WAIT_OBJECT_1) 
    { 
     // got the termination event 
     break; 
    } 
} 


/// "Main" thread: 

SomeGlobalEvent = CreateEvent(NULL, false, false, NULL); 

HANDLE hThread = _beginthread(ThreadProc, 4096, NULL); 

.... 
/// send termination signal 
SetEvent(SomeGlobalEvent); 

/// Wait for thread completion 
WaitForSingleObject(hThread); 
+3

@kakush, nếu bạn đi tới 'ShouldExit', hãy đảm bảo bạn khai báo là' biến động '.Nếu không, nó có thể không làm các trick. – eran

+0

@eran, bạn nói đúng. –

+1

@eran: Thủ thuật 'volatile' hoạt động * chỉ * cho trình biên dịch Visual C++. Nó có thể không hoạt động trên các trình biên dịch khác. –

3

Điều tốt nhất là đọc tài liệu một cách cẩn thận. Win32 API được tài liệu hóa tốt.

từ MSDN on CreateThread in the Remarks section nó nói

thực hiện Chủ đề bắt đầu từ chức năng định bởi tham số lpStartAddr . Nếu hàm này trả về, giá trị trả về DWORD được sử dụng để chấm dứt luồng trong cuộc gọi ngầm đến hàm ExitThread. Sử dụng hàm GetExitCodeThread để nhận giá trị trả về của chuỗi.

Tiếp theo, bạn nên để chức năng nhập đề xuất thực hiện công việc và kết thúc. I E. thoát khỏi vòng lặp mà sẽ trả về chức năng nhập chủ đề.

Các vấn đề liên quan