Nếu tôi có chương trình đa luồng đọc bộ nhớ loại bộ nhớ cache theo tham chiếu. Tôi có thể thay đổi con trỏ này theo chủ đề chính mà không có rủi ro về bất kỳ chủ đề nào khác đọc các giá trị không mong muốn.Việc thay đổi một con trỏ được coi là một hành động nguyên tử trong C?
Như tôi thấy, nếu thay đổi là nguyên tử, các chủ đề khác sẽ đọc giá trị cũ hơn hoặc giá trị mới hơn; không bao giờ bộ nhớ ngẫu nhiên (hoặc con trỏ null), phải không?
Tôi biết rằng có lẽ tôi nên sử dụng phương thức đồng bộ hóa, nhưng tôi vẫn tò mò.
Con trỏ có thay đổi nguyên tử không?
Cập nhật: nền tảng của tôi là 64-bit Linux (2.6.29), mặc dù tôi muốn một câu trả lời cross-platform cũng :)
Thực ra, tôi không nghĩ rằng trình biên dịch C (hoặc C++) có thể sắp xếp lại lệnh workDone = 1 thành TRƯỚC KHI một cuộc gọi hàm trước nó, trừ khi nó biết cái gì khác về workDone (như từ khóa "noalias" không được chấp nhận). Mặt khác, nếu bạn có foo = bar; qwerty = uiop; workDone = 1, sau đó workDone = 1 có thể di chuyển (hoặc thậm chí tạm thời là giá trị chỉ đăng ký, nếu workDone không biến động). Nếu ReceiveResultsOfWork nhìn vào qwerty hoặc foo, nó có thể không nhận được uiop hoặc bar, mặc dù workDone là 1. Tôi phải kiểm tra xem điều gì sẽ xảy ra nếu DoWork() kết thúc bằng nội tuyến. – jesup
Trình biên dịch có thể thực hiện việc sắp xếp lại nếu nó có thể chứng minh rằng DoWork không truy cập workDone theo bất kỳ cách nào được xác định. Điều này thực sự có thể xảy ra nếu DoWork đủ nhỏ và trong cùng một đơn vị dịch và trình biên dịch quyết định nội tuyến nó. – derobert
Điều quan trọng là trình biên dịch không bị ràng buộc bởi tiêu chuẩn để đảm bảo workDone được ghi vào sau cuộc gọi đến DoWork(). Trong thực tế, bạn chắc chắn là đúng - nếu DoWork() là một hàm thực sự gọi trình biên dịch prbably sẽ không tái sắp xếp. Nếu DoWork được inlined, workDone có thể dễ dàng được sắp xếp lại trước DoWork() hoặc trong nó. – Michael