2010-09-17 23 views
10

Làm thế nào để trình biên dịch C++ thực hiện lưu trữ cục bộ luồng trong C++ 0xTrình biên dịch C++ thực hiện lưu trữ cục bộ luồng trong C++ 0x như thế nào?

Tôi đã tìm kiếm trong Google. Nhưng tôi không thể tìm thấy bất cứ điều gì về điều này.

Có ai có bất kỳ tài liệu nào về vấn đề này không ??

+0

Tiêu chuẩn C++ có chi tiết triển khai bằng không (hoặc rất ít). –

+0

Giờ đây, bạn có thể trợ giúp: http://www.akkadia.org/drepper/tls.pdf –

Trả lời

13

Hãy đọc số Wikipedia entry.

Bộ nhớ cục bộ không phải là thứ đặc trưng cho C++. Đôi khi nó đi theo các tên khác nhau, như "TLS" (chỉ viết tắt của bộ nhớ cục bộ) hoặc "lưu trữ theo chủ đề cụ thể" (TSS).

Hầu hết các hệ điều hành đều cung cấp API để truy cập bộ nhớ theo luồng. Ví dụ: Windows có số bunch of API functions bắt đầu bằng "TLS". Dưới mui xe, Win32 có một khu vực đặc biệt cho một loạt các dữ liệu trên mỗi luồng, bao gồm cả lưu trữ cục bộ của người dùng, có thể truy cập thông qua một thanh ghi CPU cụ thể (FS trên x86). Linux cung cấp lưu trữ theo chủ đề cụ thể thông qua các API pthread, với các tên như pthread_key_create và chúng thường được triển khai bằng cách sử dụng một kỹ thuật tương tự.

Có thể một hệ điều hành không cung cấp bất kỳ hỗ trợ nào. Tuy nhiên, nếu hệ điều hành cung cấp một ID luồng quá trình duy nhất thông qua một API, thì thư viện thời gian chạy C++ có thể duy trì một cái gì đó theo khái niệm như một số std::map<thread_id, per_thread_storage> trong nội bộ. Tất nhiên, sau đó có một vấn đề của những gì per_thread_storage là. Nếu một chương trình được liên kết tĩnh, nó có thể chỉ là một cái gì đó giống như một con trỏ tới một cấu trúc lớn với tất cả các biến lưu trữ thread-local được khai báo trong chương trình như là các phần tử. Đây là một sự đơn giản hóa, nhưng bạn có được ý tưởng chung.

Truy cập các biến lưu trữ cục bộ theo chủ đề rõ ràng không chỉ là đọc hoặc ghi bộ nhớ thẳng. Nó có khả năng liên quan nhiều hơn thế. Nếu bạn định sử dụng lưu trữ thread-local/cụ thể rất nhiều trong một hàm cụ thể, tôi khuyên bạn nên sao chép con trỏ lưu trữ thread-local vào một biến cục bộ trước tiên.

+2

Bạn đã trả lời cách nhà phát triển ứng dụng có thể triển khai TLS nhưng không phải cách trình biên dịch và trình tải xử lý từ khóa chủ đề C++ 0x – doron

+6

@ doron: Trình biên dịch và trình tải hoặc sử dụng API được cung cấp bởi hệ điều hành, hoặc chúng làm một cái gì đó tương đương với kỹ thuật bản đồ, mà không có trình lập trình ứng dụng phải viết bất kỳ mã nào. – Doug

4

Biến toàn cầu (hoặc dữ liệu tĩnh có thể ghi - WSD) thường được lưu trữ trong khối bộ nhớ tách biệt với ngăn xếp, đống và mã. Khối WSD được tạo và được khởi tạo trước khi mã thực thi bắt đầu chạy.

C++ 0x giới thiệu từ khóa thread_local đảm bảo rằng một phiên bản riêng biệt của biến toàn cầu được tạo cho mỗi chuỗi. Vấn đề là một khối khác nhau cần phải được nạp cho mỗi chủ đề.

Khó khăn tiếp theo là địa chỉ của biến không cố định tại thời gian liên kết và khác nhau đối với mỗi chuỗi.

Có hai cách giải quyết vấn đề này. Một là để cho trình biên dịch tạo ra một cuộc gọi hàm để có được khối chính xác trong khi lệnh kia là thay đổi ABI để lưu trữ khối TLS trong một trong các thanh ghi bộ xử lý. Điều này sau đó có thể được sử dụng với bù đắp để truy cập biến số thread_local chính xác.

Điều này khác với hỗ trợ thư viện nơi hệ điều hành lưu trữ một giá trị void* có thể được sử dụng lưu trữ con trỏ tới khối cục bộ đã được cấp phát trên vùng xử lý.

Nếu bạn muốn các chi tiết gory xem here.

0

Bạn có thể sử dụng boost::thread để xử lý có khả năng TLS trên các nền tảng khác nhau. Việc thực hiện trên mỗi mã là trong mã và sẽ giúp bạn hiểu các hệ thống khác nhau xử lý khu vực này như thế nào.

+1

Trong C++ 0x trình biên dịch không hỗ trợ TLS với từ khóa thread_local – doron

+0

Sử dụng tiền phạt, nhưng đối với bản ghi, một số trình biên dịch thực sự đã mua vào không gian vấn đề. http://gcc.gnu.org/onlinedocs/gcc-3.3.1/gcc/Thread-Local.html –

+0

Bạn nói đúng, tôi sẽ cập nhật điều này. –