2008-10-31 35 views
5

Tôi gặp vấn đề về luồng với Delphi. Tôi đoán điều này cũng phổ biến ở các ngôn ngữ khác. Tôi có một quá trình dài mà tôi làm trong một chủ đề, điền vào một danh sách trong cửa sổ chính. Nhưng nếu một số thông số thay đổi trong thời gian trung bình, thì tôi nên dừng chuỗi thực hiện hiện tại và bắt đầu từ đầu. Delphi đề nghị chấm dứt một chuỗi bằng cách đặt Terminated: = true và kiểm tra giá trị của biến này trong chuỗi. Tuy nhiên vấn đề của tôi là điều này, phần thực thi dài được chôn trong một cuộc gọi thư viện và trong cuộc gọi này tôi không thể kiểm tra biến Terminated. Vì vậy tôi phải đợi cuộc gọi thư viện này kết thúc, điều này ảnh hưởng đến toàn bộ chương trình.Làm thế nào để dừng các chuỗi thực thi dài một cách duyên dáng?

Cách ưa thích để thực hiện trong trường hợp này là gì? Tôi có thể giết sợi chỉ ngay lập tức không?

+1

Cuộc gọi thư viện dài hạn là gì? –

Trả lời

3

Các chủ đề cần phải hợp tác để đạt được tắt máy duyên dáng. Tôi không chắc chắn nếu Delphi cung cấp một cơ chế để hủy bỏ một chủ đề khác, nhưng các cơ chế như vậy có sẵn trong .NET và Java, nhưng nên được coi là một lựa chọn cuối cùng, và trạng thái của ứng dụng là không xác định sau khi chúng đã được sử dụng.

Nếu bạn có thể giết một luồng tại một điểm tùy ý, bạn có thể giết nó trong khi nó đang giữ một khóa trong bộ cấp phát bộ nhớ (ví dụ). Điều này sẽ để chương trình của bạn mở để treo khi chuỗi chính tiếp theo của bạn cần truy cập khóa đó.

9

Cách ưu tiên là sửa đổi mã để mã không chặn mà không kiểm tra hủy.

Vì bạn không thể sửa đổi mã, bạn không thể làm điều đó; bạn phải sống với thao tác nền (nhưng bạn có thể bỏ liên kết nó khỏi bất kỳ giao diện người dùng nào, để hoàn thành nó sẽ bị bỏ qua); hoặc cách khác, bạn có thể thử chấm dứt nó (API TerminateThread sẽ dứt khoát chấm dứt bất kỳ luồng nào được xử lý). Tuy nhiên, việc chấm dứt không sạch sẽ, như Rob nói, bất kỳ khóa nào được giữ bởi sợi chỉ sẽ bị bỏ qua và bất kỳ trạng thái ngang nào được bảo vệ bởi các khóa như vậy có thể ở trạng thái bị hỏng.

Bạn có thể cân nhắc việc gọi hàm trong một tệp thực thi riêng biệt không? Có lẽ bằng cách sử dụng RPC (đường ống, TCP, chứ không phải là bộ nhớ chia sẻ do cùng một vấn đề khóa), để bạn có thể chấm dứt một quá trình thay vì chấm dứt một sợi? Quá trình cô lập sẽ cung cấp cho bạn một thỏa thuận tốt hơn bảo vệ. Vì vậy, miễn là bạn không dựa vào các quy trình chéo có tên là mutexes, nó sẽ an toàn hơn nhiều so với việc giết một sợi chỉ.

+0

Điều này nghe như một lời khuyên tốt.Thực hiện cuộc gọi này trong một quá trình khác sẽ không để lại bất kỳ đường nào sau khi mất nó. – Glenner003

3

Nếu bạn không thể sửa đổi mã để kiểm tra chấm dứt, thì chỉ cần đặt mức độ ưu tiên của nó thực sự thấp và bỏ qua nó khi nó trả về.

0

tôi đã viết này trong bài trả lời đến một similar question:

tôi sử dụng một kỹ thuật ngoại lệ dựa trên đó là làm việc khá tốt cho tôi trong một số các ứng dụng Win32.

Để chấm dứt một chuỗi, tôi sử dụng Hàng đợiUserAPC để xếp hàng cuộc gọi đến một hàm phát sinh ngoại lệ. Tuy nhiên, ngoại lệ được ném không bắt nguồn từ loại "Ngoại lệ", do đó sẽ chỉ bị bắt bởi thủ tục trình bao bọc của chuỗi của tôi.

Tôi đã sử dụng ứng dụng này với ứng dụng C++ Builder rất thành công. Tôi không nhận thức được tất cả các tinh tế của Delphi vs C + + xử lý ngoại lệ, nhưng tôi mong đợi nó có thể dễ dàng được sửa đổi để làm việc.

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