2013-08-28 41 views
12

Tôi mới đến ngôn ngữ nên chịu đựng với tôi.Go có hỗ trợ các biến dễ bay hơi/không dễ bay hơi không?

Tôi tò mò về cách GO xử lý lưu trữ dữ liệu có sẵn cho chủ đề, theo nghĩa là các biến không phải cục bộ cũng có thể không biến động, chẳng hạn như trong Java chẳng hạn.

GO có khái niệm về kênh, theo đó là giao tiếp liên tục tự nhiên, có nghĩa là nó bỏ qua bộ nhớ cache của bộ xử lý và đọc/ghi trực tiếp.

Ngoài ra, không tìm thấy bất kỳ tham chiếu nào dễ bay hơi trong tài liệu về lang lang.

+0

Có một giả định ở đây là 'biến động' có nghĩa Java/.NET thay vì ý nghĩa C/C++. –

Trả lời

3

Tài liệu Go Memory Model giải thích lý do tại sao khái niệm 'dễ bay hơi' không có ứng dụng trong Go.

Loosely: Trong số những thứ khác, goroutines được tự do lưu giữ các thay đổi cục bộ goroutine được lưu trong sổ đăng ký để những thay đổi này không thể quan sát được bởi các goroutine khác. Để "tuôn" những thay đổi đó vào bộ nhớ, phải thực hiện đồng bộ hóa. Hoặc bằng cách sử dụng khóa hoặc bằng cách giao tiếp (gửi hoặc nhận kênh).

+2

Mô hình bộ nhớ Go không nói gì về lý do tại sao dễ bay hơi không được hỗ trợ, cũng không giải thích tại sao biến động không có ứng dụng trong Go. Thay vào đó, nó giải thích cách nó hoạt động. Sự tồn tại của biến động là chính xác có nghĩa là để gắn thẻ biến mà nếu không cũng sẽ làm theo các quy tắc khác nhau trong C hoặc C + +. –

+0

Còn về các biến nằm bên ngoài một hàm, chúng có thể được truy cập từ bên trong hàm không? Nếu vậy, nếu hàm đó chạy o một luồng riêng biệt, thì biến ngoài có được đồng bộ hóa với heap hay không, khi cập nhật? – Raul

+1

@GustavoNiemeyer: Nếu bạn không thể lấy được từ tài liệu đó không có nghĩa là nó không có ở đó. Và tôi đã thực sự bao gồm gợi ý của đạo hàm trong đoạn "Losely". Biến _memory_ dễ bay hơi có thể được đồng bộ hóa bằng truy cập bắt buộc (đó là những gì C thực hiện). Giá trị hiện tại chỉ trong sổ đăng ký của một số goroutine khác không thể được xử lý theo cùng một cách. Và mô hình bộ nhớ cho phép thực hiện như vậy, trong khi C sẽ không bao giờ đặt biến biến động trong đăng ký chỉ khi được cập nhật. – zzzz

5

Câu trả lời đơn giản là dễ bay hơi không được hỗ trợ bởi đặc tả Go hiện tại, thời gian.

Nếu bạn có một trong các trường hợp sử dụng khi cần thiết, chẳng hạn như truy cập bộ nhớ nguyên tử cấp thấp không được hỗ trợ bởi existingpackages trong thư viện chuẩn hoặc truy cập không bị chặn vào bộ nhớ được ánh xạ phần cứng, bạn sẽ cần liên kết trong tệp C hoặc tệp lắp ráp. Lưu ý rằng nếu bạn sử dụng C hoặc assembly được hiểu bởi bộ biên dịch GC, bạn thậm chí không cần cgo vì điều đó, vì các trình biên dịch c C/asm [568] cũng có thể xử lý nó.

Bạn có thể tìm thấy ví dụ về điều đó trong mã nguồn của Go. Ví dụ:

Grep cho nhiều trường hợp khác.

Để truy cập bộ nhớ trong Go hoạt động như thế nào, hãy xem The Go Memory Model.

10

TL; DR: Đi không có từ khóa để tạo biến an toàn cho nhiều goroutines để viết/đọc nó. Sử dụng gói sync/atomic cho điều đó. Hoặc tốt hơn là Do not communicate by sharing memory; instead, share memory by communicating.


Hai câu trả lời cho two meanings of volatile volatile Ven diagram

.NET/Java đồng thời

Một số đoạn trích từ Go Memory Model.

Nếu những ảnh hưởng của một goroutine phải được quan sát bởi goroutine khác, sử dụng một cơ chế đồng bộ như một khóa hoặc kênh truyền thông để thiết lập một trật tự tương đối.

Một trong các ví dụ từ phần Incorrect Synchronization là ví dụ về việc chờ giá trị bận.

Tệ hơn nữa, không có đảm bảo rằng ghi vào thực hiện sẽ bao giờ được quan sát bởi chính, vì không có sự kiện đồng bộ hóa giữa hai chủ đề. Vòng lặp chính không được đảm bảo để hoàn thành.

Thật vậy, mã này (play.golang.org/p/K8ndH7DUzq) không bao giờ thoát.

C/C++ bộ nhớ phi tiêu chuẩn

mô hình bộ nhớ Go không cung cấp một cách để giải quyết vấn đề bộ nhớ phi tiêu chuẩn. Nếu bạn có quyền truy cập thô vào bus I/O của thiết bị, bạn sẽ cần sử dụng assembly hoặc C để ghi một cách an toàn các giá trị vào các vị trí bộ nhớ. Tôi chỉ có bao giờ cần thiết để làm điều này trong một trình điều khiển thiết bị mà thường ngăn cản việc sử dụng Go.

+2

Mã được tham chiếu không thoát vì vòng lặp chính đang chặn quá trình thực thi đi. Bằng cách tăng thời gian chạy.GOMAXPROCS lên 2 mã đang thoát: https://play.golang.org/p/n-sC8jISyw – PSanetra

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