Đọc this question, tôi muốn kiểm tra xem tôi có thể chứng minh tính không nguyên tử của các lần đọc và viết trên một loại mà nguyên tử của các hoạt động đó không được đảm bảo hay không.Tại sao mã này không thể hiện tính nguyên tử của các lần đọc/ghi?
private static double _d;
[STAThread]
static void Main()
{
new Thread(KeepMutating).Start();
KeepReading();
}
private static void KeepReading()
{
while (true)
{
double dCopy = _d;
// In release: if (...) throw ...
Debug.Assert(dCopy == 0D || dCopy == double.MaxValue); // Never fails
}
}
private static void KeepMutating()
{
Random rand = new Random();
while (true)
{
_d = rand.Next(2) == 0 ? 0D : double.MaxValue;
}
}
Thật ngạc nhiên, khẳng định từ chối không thành công ngay cả sau ba phút thực thi đầy đủ. Điều gì mang lại?
- Bài kiểm tra không chính xác.
- Đặc điểm thời gian cụ thể của thử nghiệm làm cho nó khó xảy ra/không thể xác nhận sẽ thất bại.
- Xác suất quá thấp đến mức tôi phải chạy thử nghiệm lâu hơn nữa để có khả năng nó sẽ kích hoạt.
- CLR cung cấp đảm bảo mạnh hơn về nguyên tử so với thông số C#.
- Hệ điều hành/phần cứng của tôi cung cấp đảm bảo mạnh hơn CLR.
- Cái gì khác?
Tất nhiên, tôi không có ý định dựa vào bất kỳ hành vi nào không được đảm bảo rõ ràng bởi thông số kỹ thuật, nhưng tôi muốn hiểu rõ hơn về vấn đề này.
FYI, tôi chạy này trên cả hai Debug và phát hành (thay đổi Debug.Assert
-if(..) throw
) cấu hình trong hai môi trường riêng biệt:
- Windows 7 64-bit + .NET 3.5 SP1
- Windows XP 32-bit + NET 2,0
EDIT: để loại trừ khả năng bình luận John Kugelman của "trình gỡ lỗi là không Schrodinger-an toàn" là vấn đề, tôi đã thêm dòng someList.Add(dCopy);
đến KeepReading
phương pháp và veri fied rằng danh sách này không nhìn thấy một giá trị cũ duy nhất từ bộ nhớ cache.
EDIT: Dựa trên đề xuất của Dan Bryant: Sử dụng long
thay vì xóa double
ngay lập tức.
Đoán của tôi (và rất nhiều chỉ là vậy) là # 3. – AakashM
Tôi muốn kiểm tra IL để đảm bảo rằng trình biên dịch không chơi bất kỳ thủ thuật nào, nhưng khác với điều tôi không nhận được. Tôi hy vọng điều này sẽ phá vỡ trên một máy 32-bit. – mquander
Tôi sẽ tăng số lượng các chủ đề viết - cố gắng giữ các luồng N + 1 chạy trên hệ thống N-core. –