Генератор случайных чисел действительно ли C# ориентирован на многопотоковое исполнение?

Это не проблема с bs4, он делает именно то, что должен, основываясь на полученном html. Если вы посмотрите на html (НЕ IN DEV DEVLS, а скорее на res.text), у него есть src url для первых 3-х, тогда пока None не появится до 11-го элемента, который снова является первым изображением. И вот как HTML, страница динамическая.

На самом деле есть лучший способ получить изображения с помощью API. Я также немного изменил код, чтобы немного его прояснить. Я также только проверил это быстро, но, надеюсь, это поможет вам:

import requests
import webbrowser
import math
import os

query=(input("What type of images would you like? "))


req_url = 'https://unsplash.com/napi/search/photos'

params = {
'query': query,
'xp': '',
'per_page': '30',
'page': '1'}

jsonObj = requests.get(req_url, params = params).json()

numb=int(input('There are %s "%s" images.\nHow many images do you want to save? ' %(jsonObj['total'], query))) 
pages = list(range(1,math.ceil(numb/30)+1))
max_allowed = 50


fileNames = []
count = 1
for page in pages:
    params = {
            'query': query,
            'xp': '',
            'per_page': '30',
            'page': page}

    jsonObj = requests.get(req_url, params = params).json()
    for item in jsonObj['results']:
        pic_url = item['urls']['raw']
        webbrowser.open(item['urls']['raw'])

        valid_ans = False
        while valid_ans == False:
            ans = input("Do you want to save it? (y/n) ")
            if ans.lower() == "y":
                name=input("How to name it? ")
                fileName=name+".jpg"
                fileNames.append(fileName)
                print ("Saving " + fileName + " to the hard drive")
                with open(os.path.join("wallpapers",fileName), 'wb') as handle:
                    response = requests.get(pic_url, stream=True)
                    if not response.ok:
                        print (response)
                    for chunk in response.iter_content(100000):
                        handle.write(chunk)                
                valid_ans = True

            elif ans.lower() == "n":
                valid_ans = True
                pass

            else:
                print ('Invalid response.')

        count += 1
        if count > numb:
            print ('Reached your desired number of %s images.' %(numb))
            break
        if count > max_allowed:
            print ('Reached maximum number of %s images allowed.' %(max_allowed))
67
задан Mark Amery 29 August 2017 в 21:06
поделиться

5 ответов

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

У Джона Скита есть пара хороших постов на эту тему:

StaticRandom
Возвращение к случайности

Как отмечают некоторые комментаторы, есть еще одна потенциальная проблема при использовании различных экземпляров Random , которые являются исключающими потоки, но имеют одинаковые начальные значения и поэтому вызывают идентичные последовательности псевдослучайных чисел, потому что они могут быть созданы одновременно или в непосредственной близости друг от друга. Одним из способов решения этой проблемы является использование главного экземпляра Random (который заблокирован одним потоком) для генерации некоторых случайных начальных чисел и инициализации новых экземпляров Random для использования каждым другим потоком. .

25
ответ дан 24 November 2019 в 14:32
поделиться

Переопределение ответа BlueRaja с помощью ThreadLocal:

public static class ThreadSafeRandom
{
    private static readonly System.Random GlobalRandom = new Random();
    private static readonly ThreadLocal<Random> LocalRandom = new ThreadLocal<Random>(() => 
    {
        lock (GlobalRandom)
        {
            return new Random(GlobalRandom.Next());
        }
    });

    public static int Next(int min = 0, int max = Int32.MaxValue)
    {
        return LocalRandom.Value.Next(min, max);
    }
}
1
ответ дан 24 November 2019 в 14:32
поделиться

Согласно документации

Любые публичные статические (Shared в Visual Basic) члены этого типа являются потокобезопасными. Любые члены экземпляра не гарантируют потокобезопасность.

http://msdn.microsoft.com/en-us/library/system.random.aspx

2
ответ дан 24 November 2019 в 14:32
поделиться

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

Однако я не вижу причин, по которым это может понадобиться. Было бы более эффективно, если бы каждый поток имел свой собственный экземпляр класса Random.

14
ответ дан 24 November 2019 в 14:32
поделиться

Чтобы узнать о потокобезопасном генераторе случайных чисел, обратитесь к RNGCryptoServiceProvider . Из документации:

Thread Safety

Этот тип потокобезопасен.

1
ответ дан 24 November 2019 в 14:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: