2013-06-04 41 views
13

Tôi đang đọc và tìm hiểu về ThreadScheduler và các bài viết xung quanh Công việc và đi qua chức năng ThreadPool.UnsafeQueueUserWorkItem được sử dụng ở một trong số MSDN examples về Trình tự ThreadSchedulers. Trong MSDN description about UnsafeQueueUserWorkItem có một cảnh báo lớn rằng hàm có thể là lỗ hổng bảo mật và rằng "không truyền bá ngăn xếp cuộc gọi".UnsafeQueueUserWorkItem và chính xác "không tuyên truyền ngăn xếp cuộc gọi" nghĩa là gì?

Liên kết duy nhất là QueueUserWorkItem - từ tên - dường như là "đối tác an toàn"? nhưng cũng không đề cập gì về việc gọi ngăn xếp.

Điều đó có nghĩa là gì để tuyên truyền ngăn xếp? Sao chép nó trước khi bắt đầu công việc? Tại sao một thread khác lại cần stack của thread đang gọi? Tôi sẽ giả định rằng họ bắt đầu với một ngăn xếp mới và trống. Sau khi tất cả, khi các chức năng thread trả về, nó không tiếp tục thực hiện các chức năng lập kế hoạch nhiệm vụ, phải không?

Trả lời

16

Đây là chi tiết triển khai CAS, Mã bảo mật truy cập. Mà có thể kiểm tra xem một sợi có đủ quyền để thực hiện một hoạt động. Nó chỉ quan trọng nếu mã chạy trong một môi trường bảo mật bị hạn chế, không chạy với sự tin tưởng đầy đủ hoặc trong một sandbox.

Đường ống dẫn nước khiến công việc này phức tạp và tôi chỉ có thể ước tính cách hoạt động của nó. Lớp ExecutionContext là khóa, nó xác định ngữ cảnh bảo mật trong đó mã chạy. Mọi thứ trở nên khó khăn khi một chuỗi chạy với quyền hạn chế bắt đầu một chuỗi khác. Rõ ràng là các luồng khác cần chạy với cùng một loại hạn chế như là chuỗi ban đầu. CAS phụ thuộc vào việc có thể thực hiện các bước đi bộ để khám phá các hạn chế. Đó là khó khăn trên một sợi khác, nó có ngăn xếp riêng của nó.

Phương thức ExecutionContext.Capture() thực hiện vai trò thiết yếu ở đây. Nó tạo ra một bản sao của bối cảnh của chuỗi gọi, bao gồm cả việc tạo một ngăn xếp ngăn xếp để tạo một ngăn xếp "nén" của các thuộc tính bảo mật được phát hiện. Chuỗi mới sau đó chạy với bối cảnh đã chụp đó.

ThreadPool.UnsafeQueueUserWorkItem() bỏ qua cuộc gọi Capture(). Chuỗi threadpool sẽ chạy với ngữ cảnh thực thi mặc định.

Đây là một tối ưu hóa, Capture() không phải là một phương pháp rẻ tiền. Nó quan trọng trong các loại chương trình mà phụ thuộc vào chủ đề TP để có được công cụ thực hiện trong một vội vàng. Một máy chủ web nhảy vào tâm trí. Ngoài ra các loại mã sử dụng phương pháp, bạn thấy nó được sử dụng trong các phương pháp nội bộ trong không gian tên System.Net ví dụ.

Rõ ràng nó không an toàn, nó không chạy với các hạn chế CAS của chuỗi gốc.

+1

Ah, tôi hiểu. Rất thú vị. Bây giờ ... điều này có bất kỳ sự khác biệt hiệu suất khi _not_ chạy dưới bất kỳ môi trường bảo mật nào không? – Imi

+0

Không phải cách hoạt động, kiểm tra CAS luôn được thực hiện. Stack đi bộ có một chi phí cố định phụ thuộc vào chiều sâu ngăn xếp. "Chi phí" là một từ lớn, chúng tôi đang nói về một số ít micro giây ở đây. Điều này không quan trọng chút nào cho đến khi bạn đang chạy * hàng ngàn * yêu cầu chuỗi TP mỗi giây. –

+0

_Chúng tôi đang nói về một số ít micro giây ở đây Woah .. cảm ơn vì bình luận. Tôi tốt hơn hồ sơ của tôi tùy chỉnh thread scheduler prototyp ở đây sau đó. Tôi chắc chắn có thể _not_ sống với một cái gì đó trong khoảng "micro giây". – Imi

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