2012-06-12 29 views
18

Như thế này.Bạn có thể sử dụng các biến cục bộ luồng trong một lớp hoặc cấu trúc

struct some_struct 
{ 
// Other fields 
..... 
__thread int tl; 
} 

Tôi đang cố gắng làm điều đó nhưng trình biên dịch đang cho tôi lỗi này.

./cv.h:16:2: error: '__thread' is only allowed on variable declarations 
     __thread int tl; 
+1

Vui lòng đăng lỗi trình biên dịch bạn đang nhận được. –

+0

AFAICS '__thread' không phải là tiêu chuẩn. Bạn đang sử dụng trình biên dịch nào? –

Trả lời

12

Bộ nhớ cục bộ chỉ áp dụng cho các biến tĩnh. Không có điểm trong việc tạo cấu trúc non-static hoặc các thành viên của lớp-local.

Biến cục bộ (tự động) luôn dành riêng cho chuỗi thực thi mã, nhưng biến toàn cục và biến tĩnh được chia sẻ giữa các chuỗi vì chúng nằm trong phân đoạn dữ liệu hoặc BSS. TLS cung cấp một cơ chế để làm cho các biến toàn cầu cục bộ thành luồng và đó là những gì mà từ khóa __thread đạt được - nó hướng dẫn trình biên dịch tạo ra một bản sao riêng biệt của biến trong mỗi luồng trong khi từ điển nó vẫn là một biến toàn cục. các hàm khác nhau được gọi trong cùng một luồng thực thi).

Thành viên và cấu trúc lớp không tĩnh được đặt ở cùng một nơi mà đối tượng (lớp hoặc cấu trúc) được phân bổ - hoặc trên ngăn xếp nếu một biến tự động được khai báo hoặc trong heap nếu sử dụng new hoặc malloc(). Dù bằng cách nào, mỗi luồng sẽ nhận được một vị trí lưu trữ duy nhất cho biến và __thread chỉ không áp dụng được trong trường hợp này do đó lỗi trình biên dịch bạn nhận được.

+6

Không phải với ý nghĩa hiện tại của __thread hoặc thread_local nhưng có khá một số tình huống mà nó có ý nghĩa để có một thành viên khác nhau cho mỗi thread, gói lên độc đáo đằng sau một số giao diện. – PlasmaHH

+9

Tôi phải không đồng ý - chỉ vì một đối tượng được tạo ra bởi một chuỗi duy nhất không có nghĩa là nó sẽ được thao tác chỉ bằng một luồng (ví dụ: cấu trúc dữ liệu không có khóa). Phải thừa nhận rằng, điều này là tương đối hiếm, tuy nhiên. – Cameron

+0

Tôi sẽ đánh giá cao nếu bất kỳ downvoters sẽ chăm sóc để đăng một ví dụ contra hoặc một câu trả lời tốt hơn hoặc cung cấp các đề xuất về cách chỉnh sửa các câu hỏi hoặc chỉnh sửa các câu hỏi chính mình. –

6

gcc áp đặt các restrictions sau về việc sử dụng __thread:

Từ khoá __thread có thể được áp dụng cho bất kỳ toàn cầu, tập tin scoped tĩnh, chức năng-scoped tĩnh, hoặc dữ liệu tĩnh thành viên của một lớp học. Nó có thể không được áp dụng cho thành viên dữ liệu tự động hoặc không có phạm vi khối.

Trình sửa đổi __thread được hỗ trợ bởi nhiều trình biên dịch. Nó không phải là không thể nghĩ rằng các hạn chế chính xác khác nhau một chút từ trình biên dịch để trình biên dịch.

0

Theo sách Petzold 'Lập trình Windows' (trang 1241), bạn đánh dấu một biến là chuỗi địa phương bằng cách sử dụng các từ khóa: __declspec (thread). Ví dụ: __declspec (thread) int iGlobal = 1;

Tôi nghi ngờ điều này có thể được thực hiện trong lớp học. Bạn cũng có thể biến biến tĩnh thành quá. [sửa] chỉ nhận ra bạn có lẽ không chạy trên cửa sổ ... Vì vậy, tôi đoán cho bất cứ ai cần một cửa sổ câu trả lời, điều này có thể có liên quan.

4

C11 chuẩn Mục 6.7.1 khoản 2

Tại hầu hết, người ta lưu trữ lớp specifier có thể được đưa ra trong specifiers khai trong một tuyên bố , ngoại trừ việc _Thread_local thể xuất hiện với tĩnh hoặc extern. 120)

Chuẩn C11 Mục 6.7.1. Khoản 3

Trong tuyên bố của một đối tượng với phạm vi khối, nếu specifiers khai bao gồm _Thread_local thì cũng bao gồm một trong hai tĩnh hoặc extern. Nếu _Thread_local xuất hiện trong bất kỳ tuyên bố nào của một đối tượng, nó sẽ có mặt trong mọi tuyên bố của đối tượng đó.

+1

Tôi đoán bạn có nghĩa là C11, không? C99 không có mô hình chuỗi và tất cả điều đó. –

+0

Đã sửa. Thói quen viết C99. – phoxis

0

Đối với C, điều này không có ý nghĩa lắm, các thành viên static (= chung) chỉ là tính năng của C++. Và do đó, tiêu chuẩn C11 mới (giới thiệu _Thread_local) không cho phép nó. Những con thú được cho phép về cơ bản ở khắp mọi nơi là một biến với thời gian lưu trữ tĩnh được cho phép.

Đối với C++, điều này có thể có ý nghĩa bên trong một lớp tương tự với thành viên static, nhưng nếu điều này được cho phép bởi C++ 11, tôi không biết.

+0

Có vẻ như không được phép, tôi nhận C2720 với VS2015: https://msdn.microsoft.com/en-us/library/w8x1t4f0.aspx –

1

Bạn nên thay đổi __thread int tl; thành thread_local static int tl;

+1

Sau đó, bạn không thể có nhiều phiên bản của cấu trúc/lớp có các giá trị khác nhau trong lĩnh vực này. – rustyx

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