Что “ориентированный на многопотоковое исполнение” действительно означает … На практике

терпите мои вопросы о новичке..

Я пытался преобразовать PDF в PNG с помощью ghostscript с ASP.NET и C#. Однако я также считал, что ghostscript не ориентирован на многопотоковое исполнение. Таким образом, мои вопросы:

  1. То, что точно делает "ghostscript, не ориентировано на многопотоковое исполнение" среднее на практике? Какое влияние это оказывает, если я использую его в живом ASP.NET (aspx) веб-приложение со многими параллельными пользователями, получающими доступ к нему одновременно?

  2. Я также читал из другого сайта что основная функция ghostscript ver. 8.63 многопоточный рендеринг. Это означает, что наш ориентированный на многопотоковое исполнение вопрос теперь решен? Действительно ли ghostscript ориентирован на многопотоковое исполнение теперь?

  3. Я также оцениваю PDF2Image от PDFTron, который, как предполагается, ориентирован на многопотоковое исполнение. Но на лицензию ЦП не обходится дешево. Действительно ли стоит оплатить дополнительные деньги "ориентированный на многопотоковое исполнение" по сравнению с "не безопасный"?

43
задан Hakan Fıstık 18 July 2017 в 09:16
поделиться

6 ответов

Учитывая, что Коллекция, например, не является трехбезопасной:

var myDic = new Dictionary<string, string>();

В многопоточной среде это вызовет:

string s = null;
if (!myDic.TryGetValue("keyName", out s)) {
    s = new string('#', 10);
    myDic.Add("keyName", s);
}

Поскольку один поток работает, пытаясь добавить KeyValuePair в словарь myDic, другой может TryGetValue ( ). Поскольку Коллекции нельзя читать и писать одновременно, возникнет исключение.

Однако, с другой стороны, если вы попробуете это:

// Other threads will wait here until the variable myDic gets unlocked from the preceding thread that has locked it.
lock (myDic) {
    string s = null;
    if (!myDic.TryGetValue("keyName", out s)) {
        s = new string('#', 10);
        myDic.Add("keyName", s);
    }
} // The first thread that locked the myDic variable will now release the lock so that other threads will be able to work with the variable.

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

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

2. Я не думаю, что GhostScript теперь является потокобезопасным. Он в основном использует несколько потоков для выполнения своих задач, поэтому это повышает производительность, вот и все.

3. В зависимости от вашего бюджета и требований, он может оказаться достойным. Но если вы строите вокруг оболочки, вы могли бы, возможно, использовать lock () только там, где это удобно, или, если вы сами не используете многопоточность, определенно не стоит платить за безопасность потоков. Это означает только то, что если ВАШЕ приложение использует многопоточность, то вы не испытаете последствий того, что библиотека не будет потокобезопасной. Если вы действительно не используете многопоточность, не стоит платить за поточно-ориентированную библиотеку.

22
ответ дан 26 November 2019 в 22:50
поделиться

Трудно дать точное техническое определение, с которым все согласны.

Неформально «потокобезопасность» просто означает «разумно хорошо ведет себя при вызове из нескольких потоков». При вызове из нескольких потоков объект не выйдет из строя и не даст сумасшедших результатов.

Если вы собираетесь выполнять многопоточное программирование с использованием определенного объекта, вам действительно нужно получить ответ: «Какую модель потоковой обработки ожидает объект?»

Существует множество различных моделей потоковой передачи. Например, модель «свободного потока» - это «делайте из любого потока все, что хотите; объект будет с этим справляться». Это самая простая модель для вас, и ее сложнее всего предоставить поставщику объектов.

На другом конце спектра находится «однопоточная» модель - все экземпляры всех объектов должны быть доступны из одного потока, точка.

А еще куча вещей посередине. Модель «многоквартирных потоков» - это «вы можете создать два экземпляра в двух разных потоках, но какой бы поток вы ни использовали для создания экземпляра, это тот поток, который вы всегда должны использовать для вызова методов в этом экземпляре».

Модель «арендованных потоков» - это «вы можете вызвать один экземпляр в двух разных потоках, но вы несете ответственность за то, чтобы никакие два потока никогда не выполняли это одновременно».

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

37
ответ дан 26 November 2019 в 22:50
поделиться

Если вы используете ghostscript из объекта оболочки (т. Е. Запускаете командную строку для обработки файла), вы не столкнетесь с проблемами потоковой передачи, потому что каждый запущенный экземпляр будет в другом процессе на сервере. Когда вам нужно быть осторожным, так это когда у вас есть dll, которую вы используете из C # для обработки PDF, этот код необходимо синхронизировать, чтобы два потока не выполняли один и тот же код одновременно.

3
ответ дан 26 November 2019 в 22:50
поделиться

1) Это означает, что если вы используете одни и те же объекты или поля Ghostscript в нескольких потоках, произойдет сбой. Например:

private GhostScript someGSObject = new GhostScript();
...
// Uh oh, 2 threads using shared memory. This can crash!
thread1.Use(someGSObject);
thread2.Use(someGSObject);

2) Я так не думаю - многопоточный рендеринг предполагает, что GS внутренне использует несколько потоков для рендеринга. Он не решает проблему небезопасности GS для использования в нескольких потоках.

3) Есть ли там вопрос?

Чтобы сделать GhostScript потокобезопасным, убедитесь, что к нему одновременно обращается только 1 поток. Вы можете сделать это с помощью блокировок:

lock(someObject)
{
   thread1.Use(someGSObject);
}
lock(someObject)
{
   thread2.Use(someGSObject);
}
10
ответ дан 26 November 2019 в 22:50
поделиться

В общем, это неоднозначный термин.

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

Иногда это означает, что параллелизм определяется на уровне языка. т.е. модель памяти языка поддерживает параллелизм. Это сложно! потому что как автор библиотеки вы не можете создавать параллельные библиотеки, потому что язык не имеет гарантий для многих основных примитивов, которые необходимы для использования. Это больше касается разработчиков компиляторов, чем пользователей библиотек. В этом смысле C # является потокобезопасным.

Я знаю, что не ответил на ваш вопрос напрямую, но надеюсь, что это поможет.

1
ответ дан 26 November 2019 в 22:50
поделиться
  1. Потоковая безопасность в основном означает, что часть кода будет работать правильно даже при доступе из нескольких потоков. Если в многопоточном приложении используется небезопасный для потоков код, могут возникнуть множественные проблемы. Самая частая проблема - это взаимоблокировка. Однако есть гораздо более гнусные проблемы (состояния гонки), которые могут быть более серьезной проблемой, потому что проблемы с потоками, как известно, сложно отлаживать.

  2. Нет. Многопоточный рендеринг просто означает, что GS сможет рендерить быстрее, потому что он использует потоки для рендеринга (в теории, во всяком случае - не всегда так на практике).

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

2
ответ дан 26 November 2019 в 22:50
поделиться
Другие вопросы по тегам:

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