Сообщение Re[11]: Для тех, кто смеется над JavaScript от 17.06.2020 9:34
Изменено 17.06.2020 9:35 Pauel
Re[11]: Для тех, кто смеется над JavaScript
Здравствуйте, Sharov, Вы писали:
H>>Это интересно. А как там с многопоточностью, в движке ноды? Как разграничивается доступ к общему ресурсу из нескольких потоков?
S>Он однопоточных и асинхронный. Доступ по идее будет сериализуемым.
Это фатальное заблуждение. В ноде никакого серилизуемого доступа. Он однопоточный, но тем не менее многозадачный. Те самые колбеки и тд, это кооперативная многозадачность. То есть, недетерминизм в полный рост. Только гонки надо искать не из за потоков, а из за колбеков.
Например, операция доступа к ресурсу следующая —
В итоге, ресурс хранит данные всех шагов некоторого вычисления и в хидере указаны соответствующие ссылки.
Теперь представим, что будет, если сделаем, скажем, вот такую хрень
То есть, мы здесь запустили 6 параллельных цепочек, каждая из которых работает с одним и тем же разделяемым ресурсом.
Вопрос — что будет в конце? А будет хаос, содержимое файла скорее всего будет представлять непойми что — одна цепочка обновила хидер, этот хидер тут же перезаписывается другой цепочкой. Она цепочка сделала запись в конец, но по этому же смещению тут же пишет другая цепочки.
А если вот так:
Вот это сериализуемый доступ, и сделано это руками
H>>Это интересно. А как там с многопоточностью, в движке ноды? Как разграничивается доступ к общему ресурсу из нескольких потоков?
S>Он однопоточных и асинхронный. Доступ по идее будет сериализуемым.
Это фатальное заблуждение. В ноде никакого серилизуемого доступа. Он однопоточный, но тем не менее многозадачный. Те самые колбеки и тд, это кооперативная многозадачность. То есть, недетерминизм в полный рост. Только гонки надо искать не из за потоков, а из за колбеков.
Например, операция доступа к ресурсу следующая —
async update(path, pattern) {
const resource = await open(path); // доступ к ресурсу разделяемый, а не эксклюзивный !!!
const oldHeader = await readHeader(resource);
const {newPattern, newHeader} = await nextStep(pattern, oldHeader);
await writeToEnd(resource, newPattern);
await updateHeader(resource, newHeader);
await close(resource);
}
В итоге, ресурс хранит данные всех шагов некоторого вычисления и в хидере указаны соответствующие ссылки.
Теперь представим, что будет, если сделаем, скажем, вот такую хрень
update(path, pattern1);
update(path, pattern2);
update(path, pattern3);
update(path, pattern4);
update(path, pattern5);
update(path, pattern6);
То есть, мы здесь запустили 6 параллельных цепочек, каждая из которых работает с одним и тем же разделяемым ресурсом.
Вопрос — что будет в конце? А будет хаос, содержимое файла скорее всего будет представлять непойми что — одна цепочка обновила хидер, этот хидер тут же перезаписывается другой цепочкой. Она цепочка сделала запись в конец, но по этому же смещению тут же пишет другая цепочки.
А если вот так:
await update(path, pattern1);
await update(path, pattern2);
await update(path, pattern3);
await update(path, pattern4);
await update(path, pattern5);
await update(path, pattern6);
Вот это сериализуемый доступ, и сделано это руками
Re[11]: Для тех, кто смеется над JavaScript
Здравствуйте, Sharov, Вы писали:
H>>Это интересно. А как там с многопоточностью, в движке ноды? Как разграничивается доступ к общему ресурсу из нескольких потоков?
S>Он однопоточных и асинхронный. Доступ по идее будет сериализуемым.
Это фатальное заблуждение. В ноде никакого серилизуемого доступа, если речь не про блокирующие вызовы. Он однопоточный, но тем не менее многозадачный. Те самые колбеки и тд, это кооперативная многозадачность. То есть, недетерминизм в полный рост. Только гонки надо искать не из за потоков, а из за колбеков и эвентлупа.
Например, операция доступа к ресурсу следующая —
В итоге, ресурс хранит данные всех шагов некоторого вычисления и в хидере указаны соответствующие ссылки.
Теперь представим, что будет, если сделаем, скажем, вот такую хрень
То есть, мы здесь запустили 6 параллельных цепочек, каждая из которых работает с одним и тем же разделяемым ресурсом.
Вопрос — что будет в конце? А будет хаос, содержимое файла скорее всего будет представлять непойми что — одна цепочка обновила хидер, этот хидер тут же перезаписывается другой цепочкой. Она цепочка сделала запись в конец, но по этому же смещению тут же пишет другая цепочки.
А если вот так:
Вот это сериализуемый доступ, и сделано это руками
H>>Это интересно. А как там с многопоточностью, в движке ноды? Как разграничивается доступ к общему ресурсу из нескольких потоков?
S>Он однопоточных и асинхронный. Доступ по идее будет сериализуемым.
Это фатальное заблуждение. В ноде никакого серилизуемого доступа, если речь не про блокирующие вызовы. Он однопоточный, но тем не менее многозадачный. Те самые колбеки и тд, это кооперативная многозадачность. То есть, недетерминизм в полный рост. Только гонки надо искать не из за потоков, а из за колбеков и эвентлупа.
Например, операция доступа к ресурсу следующая —
async update(path, pattern) {
const resource = await open(path); // доступ к ресурсу разделяемый, а не эксклюзивный !!!
const oldHeader = await readHeader(resource);
const {newPattern, newHeader} = await nextStep(pattern, oldHeader);
await writeToEnd(resource, newPattern);
await updateHeader(resource, newHeader);
await close(resource);
}
В итоге, ресурс хранит данные всех шагов некоторого вычисления и в хидере указаны соответствующие ссылки.
Теперь представим, что будет, если сделаем, скажем, вот такую хрень
update(path, pattern1);
update(path, pattern2);
update(path, pattern3);
update(path, pattern4);
update(path, pattern5);
update(path, pattern6);
То есть, мы здесь запустили 6 параллельных цепочек, каждая из которых работает с одним и тем же разделяемым ресурсом.
Вопрос — что будет в конце? А будет хаос, содержимое файла скорее всего будет представлять непойми что — одна цепочка обновила хидер, этот хидер тут же перезаписывается другой цепочкой. Она цепочка сделала запись в конец, но по этому же смещению тут же пишет другая цепочки.
А если вот так:
await update(path, pattern1);
await update(path, pattern2);
await update(path, pattern3);
await update(path, pattern4);
await update(path, pattern5);
await update(path, pattern6);
Вот это сериализуемый доступ, и сделано это руками