什么是“线程安全”?真正的意思是......实际上
请忍受我的新手问题。
我试图使用 Ghostscript、ASP.NET 和 C# 将 PDF 转换为 PNG。但是,我也读到 Ghostscript 不是线程安全的。所以我的问题是:
- “ghostscript 不是线程安全的”在实际中到底意味着什么?如果我在实时 ASP.NET(aspx) Web 应用程序中使用它,并且有许多并发用户同时访问它,会产生什么影响?
我还从另一个网站了解到 Ghostscript ver. 的主要功能。 8.63是多线程渲染。这是否意味着我们的线程安全问题现在已经解决了? Ghostscript 现在线程安全了吗?
我还在评估来自 PDFTron 的 PDF2Image,它应该是线程安全的。但每个 CPU 的许可证并不便宜。是否值得为“线程安全”与“不安全”支付额外的钱?
please bear with my newbie questions..
I was trying to convert PDF to PNG using ghostscript, with ASP.NET and C#. However, I also read that ghostscript is not thread safe. So my questions are:
What exactly does "ghostscript is not thread safe" mean in practical terms? What impact does it have if I use it in a live ASP.NET(aspx) web application with many concurrent users accessing it at the same time?
I also read from another site that the major feature of ghostscript ver. 8.63 is multithreaded rendering. Does this mean our thread safe issue is now resolved? Is ghostscript thread safe now?
I am also evaluating PDF2Image from PDFTron, which is supposed to be thread safe. But the per CPU license doesn't come cheap. Is it worth paying the extra money for "thread safe" vs "not safe"?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
很难提出一个大家都同意的精确技术定义。
通俗地说,“线程安全”只是意味着“从多个线程调用时表现相当良好”。当从多个线程调用时,该对象不会崩溃或产生疯狂的结果。
如果您打算进行涉及特定对象的多线程编程,那么您实际上需要回答的问题是“该对象期望的线程模型是什么?”
有许多不同的线程模型。例如,“自由线程”模型是“从任何线程做任何你想做的事情;对象将处理它”。这是您最容易处理的模型,也是对象提供者最难提供的模型。
另一方面是“单线程”模型——所有对象的所有实例都必须从单个线程访问。
然后中间还有一堆东西。 “公寓线程”模型是“您可以在两个不同的线程上创建两个实例,但是无论您使用什么线程创建实例,您都必须始终使用该线程来调用该实例上的方法”。
“租用线程”模型是“您可以在两个不同的线程上调用一个实例,但您有责任确保没有两个线程同时这样做”。
等等。在尝试针对对象编写线程代码之前,先了解对象所需的线程模型。
A precise technical definition that everyone agrees on is difficult to come up with.
Informally, "thread safe" simply means "is reasonably well-behaved when called from multiple threads". The object will not crash or produce crazy results when called from multiple threads.
The question you actually need to get answered if you intend to do multi-threaded programming involving a particular object is "what is the threading model expected by the object?"
There are a bunch of different threading models. For example, the "free threaded" model is "do whatever you want from any thread; the object will deal with it." That's the easiest model for you to deal with, and the hardest for the object provider to provide.
On the other end of the spectrum is the "single threaded" model -- all instances of all objects must be accessed from a single thread, period.
And then there's a bunch of stuff in the middle. The "apartment threaded" model is "you can create two instances on two different threads, but whatever thread you use to create an instance is the thread you must always use to call methods on that instance".
The "rental threaded" model is "you can call one instance on two different threads, but you are responsible for ensuring that no two threads are ever doing so at the same time".
And so on. Find out what the threading model your object expects before you attempt to write threading code against it.
例如,假设集合不是威胁安全的:
在多线程环境中,这将抛出:
当一个线程正在尝试将 KeyValuePair 添加到字典 myDic 时,另一个线程可能会 TryGetValue()。由于集合不能同时读取和写入,因此会发生异常。
但是,另一方面,如果您尝试这样做:
然后突然,尝试获取相同“keyName”键值的第二个线程将不必将其添加到字典中,因为第一个线程已经添加了它。
所以简而言之,线程安全意味着一个对象支持同时被多个线程使用,或者会为你适当地锁定线程,而你不必担心线程安全。
2. 我认为 GhostScript 现在不是线程安全的。它主要使用多个线程来执行其任务,因此这使其提供了更高的性能,仅此而已。
3.根据您的预算和要求,这可能是值得的。但如果你围绕包装器构建,你可能只能在方便的地方使用 lock() ,或者如果你自己不使用多线程,那么绝对不值得为线程安全付出代价。这仅意味着如果您的应用程序使用多线程,那么您将不会遭受库不线程安全的后果。除非你真的是多线程的,否则不值得为线程安全库付费。
Given that a Collection, for instance, is not threasafe:
In a multhread environment, this will throw:
As one thread is working trying to add the KeyValuePair to the dictionary myDic, another one may TryGetValue(). As Collections can't be read and written at the same time, an Exception will occur.
However, on the other hand, if you try this:
Then suddenly, the second thread trying to get the same "keyName" key value will not have to add it to the dictionary as the first thread already added it.
So in short, threadsafe means that an object supports being used by multiple threads at the same time, or will lock the threads appropriately for you, without you having to worry about threadsafety.
2. I don't think GhostScript is now threadsafe. It is majorly using multiple threads to perform its tasks, so this makes it deliver a greater performance, that's all.
3. Depending on your budget and your requirements, it may be worthy. But if you build around wrapper, you could perhaps only lock() where it is convenient to do so, or if you do not use multithreading yourself, it is definitely not worth to pay for threadsafety. This means only that if YOUR application uses multithreading, then you will not suffer the consequences of a library not being threadsafe. Unless you really multihread, it is not worth paying for a threadsafe library.
我是一名 Ghostscript 开发人员,不会重复有关线程安全的一般理论。
我们一直致力于使 GS 成为线程安全的,以便可以在单个进程中使用 gsapi_new_instance 创建多个“实例”,但是我们还没有满意地完成这个任务(包括我们对此的 QA 测试)。
但是,图形库是线程安全的,多线程渲染依赖于此来允许我们生成多个线程来渲染带并行地从显示列表中。多线程渲染已经过大量 QA 测试,并被许多商业许可持有者用来提高多核 CPU 的性能。
您可以打赌,我们将宣布何时最终支持 GS 的多个实例。大多数想要在需要多个实例的应用程序中使用当前 GS 的人会为每个实例生成单独的进程,因此 GS 不需要是线程安全的。 GS 可以运行由参数列表选项确定的作业,或者可以通过管道将 I/O 传送到进程或从进程传送 I/O 以提供数据并收集输出。
I am a Ghostscript developer, and won't repeat the general theory about thread safety.
We have been working on getting GS to be thread safe so that multiple 'instances' can be created using gsapi_new_instance from within a single process, but we have not yet completed this to our satisfaction (which includes our QA testing of this).
The graphics library is, however, thread safe and the multi-threaded rendering relies on this to allow us to spawn multiple threads to render bands from a display list in parallel. The multi-threaded rendering has been subjected to a lot of QA testing and is used by many commercial licensees to improve performance on multi-core CPU's.
You can bet we will announce when we finally support multiple instances of GS. Most people that want to use current GS from applications that need multiple instances spawn separate processes for each instance so that GS doesn't need to be thread safe. The GS can run a job as determined by the argument list options or I/O can be piped to/from the process to provide data and collect output.
1)这意味着如果您在多个线程之间共享相同的 Ghostscript 对象或字段,它将崩溃。例如:
2)我不这么认为 - 多线程渲染表明 GS 内部使用多个线程进行渲染。它没有解决 GS 在多线程中使用不安全的问题。
3)这里面有问题吗?
为了确保 GhostScript 线程安全,请确保一次只有 1 个线程正在访问它。您可以通过锁来做到这一点:
1) It means if you share the same Ghostscript objects or fields among multiple threads, it will crash. For example:
2) I don't think so - multithreaded rendering suggests GS is internally using multiple threads to render. It doesn't address the problem of GS being unsafe for use from multiple threads.
3) Is there a question in there?
To make GhostScript thread safe, make sure only 1 thread at a time is accessing it. You can do this via locks:
如果您从 shell 对象使用 Ghostscript(即运行命令行来处理文件),您将不会遇到线程问题,因为运行的每个实例都将在服务器上的不同进程中。需要小心的是,当您使用 C# 中的 dll 来处理 PDF 时,需要同步该代码以防止两个线程同时执行相同的代码。
If you are using ghostscript from a shell object (i.e. running a command line to process the file) you will not be caught by threading problems because every instance running will in a different process on the server. Where you need to be careful is when you have a dll that you are using from C# to process the PDF, that code would need to be synchronized to keep from two threads from executing the same code at the same time.
线程安全基本上意味着一段代码即使被多个线程访问也能正确运行。如果在线程应用程序中使用非线程安全代码,可能会出现多个问题。最常见的问题是死锁。然而,还有更多邪恶的问题(竞争条件),这可能是一个更大的问题,因为线程问题非常难以调试。
没有。多线程渲染只是意味着 GS 将能够更快地渲染,因为它使用线程进行渲染(无论如何,理论上 - 在实践中并不总是如此)。
这实际上取决于您想要使用渲染器做什么。如果您要使用多个线程访问应用程序,那么,是的,您需要担心它是线程安全的。否则,这没什么大不了的。
Thread safe basically means that a piece of code will function correctly even when accessed by multiple threads. Multiple problems can occur if you use non-thread safe code in a threaded application. The most common problem is deadlocking. However, there are much more nefarious problems (race conditions) which can be more of a problem because thread issues are notoriously difficult to debug.
No. Multithreaded rendering just means that GS will be able to render faster because it is using threads to render (in theory, anyway - not always true in practice).
That really depends on what you want to use your renderer for. If you are going to be accessing your application with multiple threads, then, yes, you'll need to worry about it being thread safe. Otherwise, it's not a big deal.
一般来说,这是一个含糊不清的术语。
线程安全可能处于概念级别,您可以在其中正确同步共享数据。这通常是图书馆作者的意思。
有时,这意味着并发性是在语言级别定义的。即该语言的内存模型支持并发。这很棘手!因为作为库编写者,您无法生成并发库,因为该语言无法保证需要使用的许多基本原语。这对编译器编写者来说比库用户更重要。从这个意义上来说,C# 是线程安全的。
我知道我没有直接回答你的问题,但希望对你有所帮助。
In general it is an ambiguous term.
Thread-Safety could be at the conceptual level, where you have correct synchronization of your shared data. This is usually, what is meant by library writers.
Sometimes, it means concurrency is defined at the language level. i.e. the memory model of the language supports concurrency. This is tricky! because as a library writer you can't produce concurrent libraries, because the language have no guarantees for many essential primitives that are needed to use. This concerns compiler writers more than library users. C# is thread-safe in that sense.
I know I didn't answer your question directly, but hope that helps.