Инициализация, прежде чем мы начнем многопоточность кода
int main(){
// X is a shared resource
initSharedResourceX();
startMultitreadingServer(); // handle requests concurrently with function handle() <- below. All handlers (run concurrently) access to X **read-only**.
}
int handle(){
return X.get(); // get() is read-only
}
Я хотел бы избежать синхронизации доступа к X путем инициализации общего ресурса, прежде чем мы начнем. Нужен ли барьер компилятора? Я могу представить, что компилятор делает что-то вроде:
int main(){
startMultitreadingServer();
}
int handle(){
if(X is not initialized) {
initSharedResourceX();
}
return X.get();
}
и, как мы видим, это нарушает нашу программу.
Я знаю, компилятор должен быть супер-умным, чтобы сделать это. В частности, компилятор должен знать, что значит инициализировать X. Таким образом, он должен быть действительно супер-супер-умным. Но можем ли мы предположить, что это не так?
Как вы думаете?
1 ответ
Если компилятор не видит код startMultitreadingServer
функции, то запрещено (по спецификации языка) перемещать любой код вокруг вызова функции.
Если компилятор видит код startMultitreadingServer
функция, то он должен найти барьер памяти (или любую операцию, которая вызывает этот эффект) внутри функции. (Любая функция запуска потока должна иметь барьер памяти внутри; это должно быть указано в ее контракте / описании). И снова, компилятор не может перемещать (по крайней мере, вперед) любой код вокруг этого барьера.
Таким образом, в любом случае компилятор не может переместить код, предшествующий вызову функции создания потока, после этого вызова.