Tôi đọc qua Anthony Williams' "C++ Concurrency in Action" và trong Chương 5, mà nói về mô hình bộ nhớ multithreading-aware mới và các hoạt động nguyên tử, và ông khẳng định:Liệu std :: nguyên tử <std::string> có hoạt động phù hợp không?
Để sử dụng
std::atomic<UDT>
cho một số người dùng định nghĩaUDT
, loại này phải có một nhà điều hành gán bản sao tầm thường.
Theo tôi được biết, điều này có nghĩa rằng chúng ta có thể sử dụng std::atomic<UDT>
nếu lợi nhuận sau đúng:
std::is_trivially_copyable<UDT>::value
Theo logic này, chúng ta không nên có thể sử dụng std::string
làm mẫu đối số cho std::atomic
và nó hoạt động chính xác.
Tuy nhiên, đoạn mã sau biên dịch và chạy với sản lượng dự kiến:
#include <atomic>
#include <thread>
#include <iostream>
#include <string>
int main()
{
std::atomic<std::string> atomicString;
atomicString.store("TestString1");
std::cout << atomicString.load() << std::endl;
atomicString.store("TestString2");
std::cout << atomicString.load() << std::endl;
return 0;
}
Đây có phải là một trường hợp hành vi undefined mà chỉ xảy ra để hành xử như mong đợi?
Cảm ơn trước!
Trình biên dịch của bạn (và việc triển khai stdlib) của bạn là gì? Tôi không thể làm cho nó trình biên dịch [ở đây] (http://coliru.stacked-crooked.com/view?id=0ce3b66093e9a0a59d5179429373eea7-e54ee7a04e4b807da0930236d4cc94dc), và thực sự đó là những gì tôi đã mong đợi –
@AndyProwl Tôi đang sử dụng VS 2012 tại thời điểm, không có CTP tháng 11. –
Khi bạn đang sử dụng nó, tôi sẽ không mong đợi để xem một vấn đề. Vấn đề sẽ phát sinh khi hai (hoặc nhiều hơn) chủ đề đã cố gắng để sửa đổi cùng một chuỗi cùng một lúc. Tại thời điểm đó, toán tử non-tầm thường của 'string' sẽ bắt đầu gây ra vấn đề. Chỉ cần gói một cái gì đó trong 'std :: atomic' không có khả năng phá vỡ mã mà sẽ là tốt mà không có nó. Đồng thời, không tuân theo các quy tắc của nó, nó sẽ không giúp mã mà sẽ bị phá vỡ mà không có nó. –