Блокировка позволяет вам заставить несколько потоков обращаться к ресурсу по одному, а не пытаться одновременно обращаться к ресурсу всем из них.
Как вы заметили, обычно требуется, чтобы потоки выполнялись одновременно,Однако представьте, что у вас есть два потока, и они оба записывают в один файл.Если они попытаются выполнить запись в один и тот же файл в одно и то же время, их выходные данные будут смешанными, и ни одному из потоков не удастся фактически вставить в файл то, что он хотел.
Теперь, возможно, эта проблема не будетприходить все время.В большинстве случаев потоки не будут пытаться записать в файл все сразу.Но иногда, может быть, один раз в тысячу пробежек, они делают.Так что, возможно, у вас есть ошибка, которая кажется случайной, и которую трудно воспроизвести, и, следовательно, ее трудно исправить.Тьфу!
Или, может быть ... и это произошло в компании, в которой я работал ... у вас есть такие ошибки, но вы не знаете, что они есть, потому что они крайне редки, если на вашем компьютере есть толькомало процессоров, и вряд ли у кого-либо из ваших клиентов их больше 4. Затем они все начинают покупать блоки по 16 процессоров ... и ваше программное обеспечение запускает столько потоков, сколько имеется процессорных ядер, так что внезапно вы получаете много сбоев или получаетеневерные результаты.
Так или иначе, вернемся к файлу.Чтобы потоки не наступали друг на друга, каждый поток должен получить блокировку файла перед записью в него.Только один поток может удерживать блокировку одновременно, поэтому только один поток может записывать в файл одновременно.Поток удерживает блокировку до завершения записи в файл, а затем снимает блокировку, чтобы другой поток мог использовать файл.
Если потоки записывают в разные файлы, эта проблема никогда не возникает.Так что это одно решение: пусть ваши потоки пишут в разные файлы, а затем объединяют их при необходимости.Но это не всегда возможно;иногда есть только одно из чего-то.
Это не обязательно файлы.Предположим, вы пытаетесь просто посчитать количество вхождений буквы «А» в кучу разных файлов, по одному потоку на файл.Вы думаете, ну, очевидно, я просто сделаю так, чтобы все потоки увеличивали одну и ту же область памяти каждый раз, когда они видят «А»Но!Когда вы увеличиваете переменную, в которой хранится счетчик, компьютер считывает переменную в регистр, увеличивает регистр и затем сохраняет значение обратно.Что, если два потока читают значение одновременно, увеличивают его в одно и то же время и сохраняют обратно одновременно?Они оба начинают, скажем, с 10, увеличивают его до 11, сохраняют 11 обратно.Таким образом, счетчику 11, когда он должен быть 12: вы потеряли один счет.
Получение блокировок может быть дорогостоящим, так как вы должны ждать, пока кто-либо еще, использующий ресурс, не будет с ним закончен.Вот почему глобальная блокировка интерпретатора Python является узким местом в производительности.Таким образом, вы можете решить вообще не использовать общие ресурсы.Вместо того, чтобы использовать одну ячейку памяти для хранения числа «A» в ваших файлах, каждый поток ведет свой подсчет, и вы добавляете их все в конце (как это ни странно, похоже на решение, которое я предложил для файлов).