2013-07-26 29 views
6

Có thể chia sẻ một biến có thể thay đổi giữa nhiều luồng trong Rust không? Với những điều sau:Chia sẻ các biến có thể thay đổi giữa các chủ đề trong Rust

fn main() { 

    let mut msg = "Hi"; 
    // ... 
    msg = "Hello, World!"; 

    do spawn { 
     println(msg); 
    } 

    do spawn { 
     println(msg); 
    } 

} 

tôi nhận được lỗi này:

error

Biến chỉ cần được readonly để các chủ đề sinh ra. Biến này phải được thay đổi mặc dù, bởi vì những gì tôi thực sự cố gắng làm là chia sẻ một HashMap giữa nhiều luồng. Theo như tôi biết không có cách nào để điền một HashMap trừ khi nó có thể thay đổi. Mặc dù có một cách để làm điều đó mặc dù, tôi vẫn quan tâm đến việc biết làm thế nào để thực hiện một cái gì đó như thế này nói chung.

Cảm ơn bạn!

Trả lời

8

Hạn chế này dự kiến ​​sẽ bị xóa trong phiên bản tương lai của ngôn ngữ. Điều đó nói rằng, bạn có thể khắc phục vấn đề này với let msg = msg; trước do spawn đầu tiên. Điều đó sẽ di chuyển giá trị msg vào một vị trí bất biến, thay đổi hiệu quả tính đột biến của nó.

+0

Điều đó đã làm được điều đó! Cảm ơn bạn! –

+1

Khi bạn nói "hạn chế này dự kiến ​​sẽ bị xóa", chính xác thì điều gì đang thay đổi? Sao chép trên chụp sẽ trở thành mặc định? Hoặc, bạn sẽ có thể nắm bắt một biến có thể thay đổi miễn là lambda của bạn được tạo sau lần gán cuối cùng cho nó? –

3

Trong trường hợp chia sẻ chuỗi "Xin chào, thế giới!", Bạn chỉ cần di chuyển biến trở lại vào vị trí bất biến (ví dụ: "let mut msg = .....; let msg = msg ; ").

Có thể bạn cũng muốn tránh tạo một bản sao riêng biệt của băm cho mỗi luồng nhận được, mặc dù trong trường hợp đó bạn cũng muốn đặt nó vào trong một ARC (trình bao bọc được tính tham chiếu nguyên tử), mà bạn ' sẽ tìm thấy trong extra::arc.

+0

Vì vậy, khi thực hiện 'cho phép msg = msg;' Rust đang tạo bản sao bất biến của 'msg' cho mỗi chuỗi được sinh ra? –

+0

@EvanByrne trong trường hợp đó Rust đang che giấu một tham chiếu có thể thay đổi trước đó với một tham chiếu mới, không thay đổi được. Tham chiếu bất biến này sau đó có thể được chuyển đến các luồng. Ít nhất đây là cách tôi hiểu hành vi này. –

3

Câu trả lời "nói chung" (về cách giữ bảng băm có thể thay đổi khi được chia sẻ) là không thể trực tiếp có thể; Rust được thiết kế đặc biệt để cấm chia sẻ trạng thái có thể thay đổi để tránh các loại lỗi nhất định và để bảo vệ một số loại an toàn nhất định (và vì các lý do khác).

Tuy nhiên, bạn có thể tạo thứ gì đó giống như bảng băm có thể thay đổi được chia sẻ. Hãy tưởng tượng rằng một nhiệm vụ duy nhất có một bảng băm có thể thay đổi. Bạn có thể viết mã để các tác vụ khác có thể gửi tin nhắn nói, về cơ bản "Cập nhật bảng băm sao cho 5 bản đồ thành 18" hoặc "Cho tôi biết 7 bản đồ nào".

Thực hiện điều này là gì? Đầu tiên, bằng cách sao chép các giá trị vào tin nhắn, không thể thực hiện một tác vụ khác để lấy mẫu trên toàn bộ bộ nhớ mà bạn đang đọc (một vấn đề an toàn lớn), và thứ hai, bằng cách viết mã gián tiếp. những gì là và không phải là một hoạt động nguyên tử; lập trình viên sẽ không biết rằng hai thông báo liên tiếp về nội dung bảng băm không nhất thiết về cùng một phiên bản của bảng băm, một giả định hoàn toàn hợp lệ (ít nhất là trong Rust, nhờ một số hạn chế khác) về hai lần đọc liên tiếp từ bảng băm, không thể chia sẻ, không thể chia sẻ.

+0

Điều đó chắc chắn giống như một cách tiếp cận đầy hứa hẹn. Có điều gì cụ thể trong thư viện chuẩn sẽ giúp tôi hoàn thành một thứ như vậy không? –

+0

Không phải là tôi biết, xin lỗi!Thư viện chuẩn vẫn đang phát triển; bạn có thể muốn xem xét tự thêm nó. –

+0

Nếu tôi tìm ra cách để làm điều đó tôi sẽ chắc chắn để làm cho nó có sẵn trên github :) –

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