2013-01-13 22 views
8

Tôi là người mới làm quen với API cửa sổ và gần đây tôi đã học được rằng tôi không nên sử dụng CreateThread và TerminateThread. Tôi chuyển sang _beginthreadex, tuy nhiên tôi không chắc chắn làm thế nào tôi có nghĩa vụ phải use _endthreadex?Tôi sử dụng _endthreadex - windows API

Ví dụ, đây là một chức năng cơ bản tôi đã được thử nghiệm với:

// MyThreadFunction - outputs "#.) I Work" and ends 
unsigned int __stdcall MyThreadFunction(void * lpParam) 
{ 
    int i = (int)lpParam; 
    cout << i << ".) I work! " << endl; 
    _endthreadex(0); 
    return 0; 
} 

là vị trí của tôi về _endthreadex có đúng không? Tôi có nó trước khi trở về 0, mà chỉ có vẻ kỳ lạ với tôi? Tôi đọc trong các trang msdn về _endthreadex rằng nó được gọi tự động khi một chức năng kết thúc, nhưng bạn nên gọi nó là để dọn dẹp bộ nhớ tốt hơn, và đó là lý do tại sao tôi thử đặt nó vào. Nó có vẻ không đúng, xin lỗi nếu đây là một câu hỏi tồi. Tôi chỉ muốn đảm bảo rằng tôi đang làm mọi thứ đúng nhất với khả năng của mình

+1

Không có gì sai khi sử dụng CreateThread. Trừ khi bạn vẫn đang sử dụng MSVC cổ đại. –

+0

@DavidHeffernan CRT được liên kết tĩnh có vấn đề rò rỉ bộ nhớ nếu bạn không sử dụng _begin/_endthread. Có một tham chiếu cho sự thay đổi này? –

Trả lời

9

Bạn thực sự không cần phải gọi số _endthreadex(). Nó sẽ tự động được gọi cho bạn sau khi hàm thread của bạn trả về.

2

Bạn không phải gọi nó như đã đề cập. Liên quan đến mã của bạn, tôi nghĩ rằng return 0; cuối cùng sẽ không được gọi vì _endthreadex() không bao giờ trả về. Điều này cũng có thể gây ra destructors của các đối tượng địa phương không được gọi (đó là những gì tôi tin rằng MSDN muốn nói), do đó, bằng cách sử dụng chức năng này thậm chí có thể có hại trong C + +. Xem xét sử dụng Boost.Thread, họ có một ngoại lệ dành riêng để kết thúc một chủ đề, mà nên làm điều đúng nếu bạn muốn chấm dứt thread ở đâu đó ở giữa.

3

Câu trả lời đã được đưa ra trong phiên bản ngắn và nếu bạn muốn biết nhiều hơn - sự trở lại từ chức năng của bạn sẽ thực sự được sử dụng làm đối số trong cuộc gọi _endthreadex. Đây là thời gian chạy khi bạn bắt đầu một luồng. Các chủ đề thực sự được bắt đầu với một điểm khởi đầu ở đâu đó trong CRT, nơi nội _callthreadstartex được thực hiện:

_endthreadex(MyThreadFunction(...)); 

Đó là, ngay sau khi bạn trở về, _endthreadex sẽ được ngay lập tức gọi cho bạn và nó sẽ thoát khỏi sợi.

Bạn có thể sử dụng nó một cách rõ ràng không? Có, bạn có thể, và mã của bạn cũng tốt vì nó không quan trọng nhiều cho dù bạn gọi nó là chính mình hoặc nó sẽ được gọi cho bạn, miễn là không có rò rỉ diễn ra trên đường (chẳng hạn như, đặc biệt, chưa được gọi là destructors của biến cục bộ).

Vì nó sẽ được gọi cho bạn, và trở về từ chức năng an toàn hơn trong việc giải phóng tài nguyên cục bộ, không có lợi ích và lợi dụng để thực hiện cuộc gọi rõ ràng.

MSDN về cơ bản giải thích chính xác cùng một quyền ở đó trong Remarks section.

Bạn có thể gọi _endthread hoặc _endthreadex một cách rõ ràng để chấm dứt chuỗi ; tuy nhiên, _endthread hoặc _endthreadex được gọi tự động khi luồng trả về từ thường trình được chuyển thành tham số là _beginthread hoặc _beginthreadex. Việc chấm dứt một chuỗi có lời gọi đến endthread hoặc _endthreadex giúp đảm bảo khôi phục đúng tài nguyên được phân bổ cho luồng.

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