Data race (или просто гонка)
Представим, что есть некий код, который запускает 2 параллельных потока, внутри каждого в цикле, например 1 млн раз, происходит одна операция:
а = а + 1
где а - одна и та же переменная (например глобальная).
Ожидаемый результат - a == 2 млн
Фактический результат - a < 2 млн. Точное значение всегда разное.
Так происходит потому что a = a + 1 для процессора на самом деле является не одной операцией, а тремя:
1. Взять из оперативки значение в переменной а и поместить ее в регистр процессора
2. Прибавить к этому значению 1 (результат суммирования лежит в регистре)
3. Сохранить результат из регистра в оперативную память
И при параллельной работе с этой переменной порядок этих операцией не гарантируется. То есть нет гарантии в каком порядке потоки ОС будут выполнять эти операции. Отсюда и возникает состояние гонки.
Пример.
Допустим есть 2 потока ОС. Работу начинает первый. a = 0
1 поток. Выполнил 1. (в регистре: 0, в оперативке а=0)
1 поток. Выполнил 2. (в регистре: 1, в оперативке а=0)
Переключение контекста (начал работу второй поток)
2 поток. Выполнил 1. (в регистре: 0, в оперативке а=0)
2 поток. Выполнил 2. (в регистре: 1, в оперативке а=0)
2 поток. Выполнил 3. (в регистре: 1, в оперативке а=1)
Переключение контекста (начал работу первый поток)
1 поток. Выполнил 3 (в регистре: 1, в оперативке а=1)
Таким образом, после того, как 2 потока сделали a = a + 1 в переменной лежит не 2, а 1.
Чтобы избежать состояния гонки надо запретить двум потокам одновременный доступ к общему участку памяти (Участок кода, где это происходит называется критическая секция).
Сделать это можно с помощью мьтекса (лок): до операции над критической секцией делаем Lock(), после операции над критической секцией делаем Unlock().
Суть этого в том, что пока один поток "держит" лок, то другой поток при попытке сделать Lock() блокируется и ждет, пока другой поток не сделает Unlock(). В результате этого все 3 операции для инкремента переменной всегда происходят атомарно и проблемы возникнуть не может.
Пример кода:
https://go.dev/play/p/BGzDCig5dGQ
Представим, что есть некий код, который запускает 2 параллельных потока, внутри каждого в цикле, например 1 млн раз, происходит одна операция:
а = а + 1
где а - одна и та же переменная (например глобальная).
Ожидаемый результат - a == 2 млн
Фактический результат - a < 2 млн. Точное значение всегда разное.
Так происходит потому что a = a + 1 для процессора на самом деле является не одной операцией, а тремя:
1. Взять из оперативки значение в переменной а и поместить ее в регистр процессора
2. Прибавить к этому значению 1 (результат суммирования лежит в регистре)
3. Сохранить результат из регистра в оперативную память
И при параллельной работе с этой переменной порядок этих операцией не гарантируется. То есть нет гарантии в каком порядке потоки ОС будут выполнять эти операции. Отсюда и возникает состояние гонки.
Пример.
Допустим есть 2 потока ОС. Работу начинает первый. a = 0
1 поток. Выполнил 1. (в регистре: 0, в оперативке а=0)
1 поток. Выполнил 2. (в регистре: 1, в оперативке а=0)
Переключение контекста (начал работу второй поток)
2 поток. Выполнил 1. (в регистре: 0, в оперативке а=0)
2 поток. Выполнил 2. (в регистре: 1, в оперативке а=0)
2 поток. Выполнил 3. (в регистре: 1, в оперативке а=1)
Переключение контекста (начал работу первый поток)
1 поток. Выполнил 3 (в регистре: 1, в оперативке а=1)
Таким образом, после того, как 2 потока сделали a = a + 1 в переменной лежит не 2, а 1.
Чтобы избежать состояния гонки надо запретить двум потокам одновременный доступ к общему участку памяти (Участок кода, где это происходит называется критическая секция).
Сделать это можно с помощью мьтекса (лок): до операции над критической секцией делаем Lock(), после операции над критической секцией делаем Unlock().
Суть этого в том, что пока один поток "держит" лок, то другой поток при попытке сделать Lock() блокируется и ждет, пока другой поток не сделает Unlock(). В результате этого все 3 операции для инкремента переменной всегда происходят атомарно и проблемы возникнуть не может.
Пример кода:
https://go.dev/play/p/BGzDCig5dGQ
package main
import (
"fmt"
"sync"
)
var a = 0
func main() {
var wg sync.WaitGroup
wg.Add(1)
go increment(&wg)
wg.Add(1)
go increment(&wg)
wg.Wait()
fmt.Println(a)
}
func increment(wg *sync.WaitGroup) {
defer wg.Done()
for i := 0; i < 1e6; i++ {
a = a + 1
}
}
👍2🔥1
Прямо сейчас произошло на работе
https://www.youtube.com/watch?v=eYBwY6zKSNk
https://www.youtube.com/watch?v=eYBwY6zKSNk
YouTube
Фитиль "Порожняк" (1969) смотреть онлайн
Смотрите на iPad: https://itunes.apple.com/ru/app/rvision-tv/id810243002
Подписывайтесь: http://www.youtube.com/subscription_center?add_user=FitilOfficial
Кинопортал RVision.tv - http://rvision.tv
Вступайте в группу: http://vk.com/rvision
Порожняк (1969)…
Подписывайтесь: http://www.youtube.com/subscription_center?add_user=FitilOfficial
Кинопортал RVision.tv - http://rvision.tv
Вступайте в группу: http://vk.com/rvision
Порожняк (1969)…
😁2
У DeliveryClub есть крутая Pro подписка, которая делает доставку бесплатной во многих местах.
Стоит 100р в месяц (первый вообще 1р). С учетом того, что сама доставка без подписки 129р за 1 раз, то это очень выгодно.
Стоит 100р в месяц (первый вообще 1р). С учетом того, что сама доставка без подписки 129р за 1 раз, то это очень выгодно.
❤1
Туалетная тема.
Давно читал эту статью, а сейчас вспомнил и заново загуглил.
https://www.bbc.com/russian/vert-fut-50002275
Давно читал эту статью, а сейчас вспомнил и заново загуглил.
https://www.bbc.com/russian/vert-fut-50002275
BBC News Русская служба
Странные туалетные привычки Запада глазами остального мира
Для большинства людей, живущих в странах Запада, такие вещи, как утренний душ, пользование туалетной бумагой и унитазом - нечто само собой разумеющееся. Но с точки зрения большей части остального мира такие привычки - это что-то странное. И не очень гигиеничное.
👍2
btw если вас напрягает дублирование в чате и в канале, из одного из них или из двух можно ливнуть :)
Че нашел! Сайт зп по европе
https://techpays.eu/countries/netherlands
https://techpays.eu/countries/netherlands
techpays.eu
Tech and Software Engineer Salaries in the Netherlands - TechPays Europe
The average total compensation is €90,497 for tech workers in the Netherlands based on 2846 salary data points. Total compensation includes salary, bonuses and equity.
Подход европейских и рускоговорящих рекрутеров.
(полезной инфы на втором скрине больше)
PS: европейские, пощадите..
(полезной инфы на втором скрине больше)
PS: европейские, пощадите..
🔥1
Узнал, что в Go оказывается есть возможность создавать плагины. То есть файлы с расширением .so подгружаемые в рантайме.
Правда нужно, чтобы версия файла и основной программы совпадала.
Также, как более гибкий аналог есть реализация от HashiCorp, но тут эти плагины - отдельные процессы, а общение через rpc.
Правда нужно, чтобы версия файла и основной программы совпадала.
Также, как более гибкий аналог есть реализация от HashiCorp, но тут эти плагины - отдельные процессы, а общение через rpc.
Заметочка.
В гексогональной архитектуре, которая по-другому называется порты и адаптеры:
порты - интерфейсы
адаптеры - реализации этих интерфейсов
В гексогональной архитектуре, которая по-другому называется порты и адаптеры:
порты - интерфейсы
адаптеры - реализации этих интерфейсов
Посоветуйте рестораны\кафешки в Москве, где заказывали еду и понравилось?
У меня в списке:
Авлабар - грузинская. Беру люля и фри, иногда хинкали
Маки Маки - роллы. Нравится сет один.
Ями Ями - пицца. Нравится пицца с уткой и горгонзолой, да и в целом ок пиццы тут.
Sky фо, и\или Bo - фо бо.
Чосон - рамен куриный.
У меня в списке:
Авлабар - грузинская. Беру люля и фри, иногда хинкали
Маки Маки - роллы. Нравится сет один.
Ями Ями - пицца. Нравится пицца с уткой и горгонзолой, да и в целом ок пиццы тут.
Sky фо, и\или Bo - фо бо.
Чосон - рамен куриный.