LOCK в многопотоке

Поддержка
  • @fox Будет только в том случае, как уже выше писал, если будет асинхронное действие. Например, если в тот тестовый скрипт добавить действие сон, после того как переменная прочитана и до того как записана, то будет коллизия :)

  • @Denis_krsk В этом и фишка, что скорее всего lock в многопотоке уже реализован, по аналогии с записью в ресурс.

  • @fox Не понял в чем фишка? В том, что коллизия будет?)

  • @fox , @Denis_krsk , @xclsv
    Например, в нескольких потоках делаю гет запрос, пересчитываю количество ссылок, которые есть в ответе, увеличиваю глобальную переменную на это количество.
    Я два дня читал про многопоточность в басе, пока не понял, что ее просто нет. Вместо нее есть возможность запускать несколько экземляров одной и той же функции в несколько потоков с возможностью чтения общих данных каждым потоком. И все. По факту многопоточности нет. Нельзя взять данные из одного потока, обработать в другом и вернуть обратно.

  • @senerg Ну нет дак нет! )

  • @denis_krsk Я думаю вы поняли, что я имел ввиду. Запустить несколько потоков можно, но с ограничениями.

  • @senerg Я уже год почти работаю с БАС, написал уйму скриптов и не было таких задач, которые я не смог решить. И кстати данные взять и обработать можно, есть ресурсы, есть глоб переменные. В конце концов есть node можете кодить там как душе угодно.

  • @denis_krsk said in LOCK в многопотоке:

    данные взять и обработать можно

    Взять и обработать можно. А несколькими потоками увеличивать одну и ту же переменную нельзя если есть асинхронные действия.

  • @denis_krsk Вы же FIFO буфер для записи из разных потоков с асинхронными действиями не сможете реализовать в БАСе?

  • @senerg said in LOCK в многопотоке:

    А несколькими потоками увеличивать одну и ту же переменную нельзя если есть асинхронные действия.

    Вы сами то поняли что написали? Чем ваши асинхронные действия помешают увеличивать глобальную переменную?

  • @senerg Если в скрипте есть асинхронные действия это нормально, я говорил только о том, что бы между чтением и записью глоб переменной их не было!

  • @senerg said in LOCK в многопотоке:

    @fox , @Denis_krsk , @xclsv
    Например, в нескольких потоках делаю гет запрос, пересчитываю количество ссылок, которые есть в ответе, увеличиваю глобальную переменную на это количество.

    То, для чего Вы пытаетесь придумать велосипед, делается иначе. Сначала в однопотоке пересчитывается количество ссылок. Затем в многопотоке эти ссылки обрабатываются.

    @senerg said in LOCK в многопотоке:

    Я два дня читал про многопоточность в басе, пока не понял, что ее просто нет. Вместо нее есть возможность запускать несколько экземляров одной и той же функции в несколько потоков с возможностью чтения общих данных каждым потоком. И все. По факту многопоточности нет. Нельзя взять данные из одного потока, обработать в другом и вернуть обратно.

    Многопоточность есть. Просто она работает не так, как Вы себе это представляете. При этом Вы не ещё даже не пытались подумать, с какими проблемами столкнётесь, если она будет работать именно так, как Вам нужно.
    Проблем не в бас и его функционале, а в том, что Вы не придумали алгоритм и не предусмотрели обработку ошибок, которые будут возникать при его реализации.

  • @xclsv said in LOCK в многопотоке:

    Проблем не в бас и его функционале, а в том, что Вы не придумали алгоритм и не предусмотрели обработку ошибок, которые будут возникать при его реализации.

    Полностью согласен. Я же не говорю, что бас вдруг стал плохим, просто при придумывании алгоритма нужно учитывать возможности и особенности бас при чем не только в многопотоке и формировать алгоритм под бас, а не придуманный алгоритм брать и натягивать на бас. Самое большое неудобство заключается в том, что нет мануала, где было бы написано, что можно а что работать не будет.

    @denis_krsk said in LOCK в многопотоке:

    Если в скрипте есть асинхронные действия это нормально, я говорил только о том, что бы между чтением и записью глоб переменной их не было

    Значит если функция, запущенная в многопотоке, сначала делает какие-то асинхронные действия, затем читает глобальную переменную, обрабаывает ее только синхронными действиями, а затем записывает полученное значение в эту же глобальную переменную, то проблем не будет не зависимо от колчества запущенных потоков?

  • @senerg

    Если в скрипте есть асинхронные действия это нормально, я говорил только о том, что бы между чтением и записью глоб переменной их не было

    Значит если функция, запущенная в многопотоке, сначала делает какие-то асинхронные действия, затем читает глобальную переменную, обрабаывает ее только синхронными действиями, а затем записывает полученное значение в эту же глобальную переменную, то проблем не будет не зависимо от колчества запущенных потоков?

    Да!

    Полностью согласен. Я же не говорю, что бас вдруг стал плохим, просто при придумывании алгоритма нужно учитывать возможности и особенности бас при чем не только в многопотоке и формировать алгоритм под бас, а не придуманный алгоритм брать и натягивать на бас. Самое большое неудобство заключается в том, что нет мануала, где было бы написано, что можно а что работать не будет.

    Ну в любом языке есть свои особенности которые учитываются. А если чего-то нет или непонятно из мануала, то это легко узнается с помощью тестов.

  • @senerg said in LOCK в многопотоке:

    Я же не говорю, что бас вдруг стал плохим

    Да, но Вы пишете, что в бас нет многопоточности. Она есть.

  • @xclsv , она есть, но с ограничениями. Вы не можете создавать новый поток когда вам вздумается. Вы не можете запустить в многопотоке функцию, в которой между чтением и записью в глобальную переменную есть асинхронное действие. И еще наверняка много других ограничений, о которых я пока не знаю. Есть так как есть, и огромная благодарность автору баса за то, что есть хоть так. Даже в текущем воложении этого более чем достаточно для 90% задач.
    Я лишь говорю о том, что нет мануала о том что можно, что нет. И пока сам носом не натыкаешься на все эти особенности о них и не узнаешь.

  • @senerg said in LOCK в многопотоке:

    Вы не можете создавать новый поток когда вам вздумается

    Да, действия new Thread() в BAS'e из коробки пока нет.

    Вы не можете запустить в многопотоке функцию, в которой между чтением и записью в глобальную переменную есть асинхронное действие.

    Почему? Всегда пользовался именно таким алгоритмом. Вам уже много раз говорили, запись в глобальную переменную работает правильно и логично. Выкиньте слово асинхронные действия из своего лексикона, пока не поймёте что это такое (без обид).


    Представьте ведро
    0_1542105445958_84c8469d-6084-4699-8115-12f726215add-изображение.png
    В него не глядя накладывают раствор 5 строителей, если строитель будет смотреть в ведро сразу как положил в него раствор, он будет всегда знать, сколько его сейчас в ведре.

    Так и с глобальной переменной, увеличить или записать новые данные в глобальную переменную можно без ограничений, но у вас может получиться неправильная логика, если проверять раствор в ведре не сразу.

  • @senerg said in LOCK в многопотоке:

    @xclsv , она есть, но с ограничениями. Вы не можете создавать новый поток когда вам вздумается. Вы не можете запустить в многопотоке функцию, в которой между чтением и записью в глобальную переменную есть асинхронное действие. И еще наверняка много других ограничений, о которых я пока не знаю. Есть так как есть, и огромная благодарность автору баса за то, что есть хоть так. Даже в текущем воложении этого более чем достаточно для 90% задач.
    Я лишь говорю о том, что нет мануала о том что можно, что нет. И пока сам носом не натыкаешься на все эти особенности о них и не узнаешь.

    Я так понял, Вы решаете задачу парсинга неизвестного количества страниц. Что мешает посчитать их количество и потом распределить в многопотоке? Не нужно будет пользоваться глобальными переменными. Не нужно будет заморачиваться с добавлением потока и асинхронными действиями. К тому же это намного эффективнее и по времени и по ресурсам. Уже предлагал это в соседней теме, может не увидели.

  • @fox Я не знаю что вы понимаете под словом "асинхронные", но я понимаю вот это, а не ведро.

    @xclsv said in LOCK в многопотоке:

    Вы решаете задачу парсинга неизвестного количества страниц. Что мешает посчитать их количество и потом распределить в многопотоке?

    Чтобы узнать количество нужно сделать запрос на страницу и в ответе посмотреть пришла ли нужная страница (или есть ли кнопка перехода на следующую страницу). Т.е. придется либо все 100 запросов делать по очереди в одном потоке, либо отправить по одному запросу в 100 потоков, какие из них правильные данные не получат, значит их нет. Но тогда всегда будут лишние запросы к несуществующим страницам.

  • @senerg said in LOCK в многопотоке:

    Чтобы узнать количество нужно сделать запрос на страницу и в ответе посмотреть пришла ли нужная страница (или есть ли кнопка перехода на следующую страницу)

    Совсем не обязательно.
    Вы можете делать запрос не к каждой странице, а, к примеру, через каждые 100 страниц. Затем уменьшать интервал вдвое каждый раз, когда ответа не будет и откатываться назад. Этот метод называется "делением отрезка пополам". Он откровенно неэффективен лишь когда у вас будет 1 страница.
    Кстати, иногда на пустые страницы серверы отдают ответ 404. Это означает, что не обязательно смотреть и парсить весь ответ. Достаточно проверить статус ответа.
    Почти все пагинаторы на сайтах написаны по какому-то алгоритму. Вы можете спарсить с первой страницы количество товаров. Зная число товаров на одной странице можно вычислить число страниц.
    У меня была ситуация, когда пагинатора не было и никак нельзя было спарсить число страниц. Вычислять по каким-то причинам тоже было невозможно. Пришлось применить военную хитрость. Я просто парсил страницы подряд, проверяя, есть ли на них данные. Если нет, поток фейлился с запретом перезапуска. Профит. В этом случае, чисто лишних запросов будет равно числу потоков. Вероятно, они будут содержать пустые ответы. Не вижу проблемы в их наличии. Обойти это можно через Прервать скрипт без галочки Мгновенное завершение. Но это не очень удобно, ибо скрипт завершится полностью, хоть и подождёт завершения каждого потока. Полагаю, функцию, вызванную в многопотоке так остановить не получится.
    Но и это не всегда работает. Вообще, нужно смотреть конкретную ситуацию. Скиньте ссылку, откуда надо спарсить число страниц. Попробуем определить оптимальный алгоритм.