什么是C++在生产代码中使用的线程池的良好开源实现(类似于boost)?
请提供您自己的示例代码或示例代码使用的链接.
在我的Java类中,我有时会ThreadLocal
主要使用一种方法来避免不必要的对象创建:
@net.jcip.annotations.ThreadSafe
public class DateSensitiveThing {
private final Date then;
public DateSensitiveThing(Date then) {
this.then = then;
}
private static final ThreadLocal<Calendar> threadCal = new ThreadLocal<Calendar>() {
@Override
protected Calendar initialValue() {
return new GregorianCalendar();
}
};
public Date doCalc(int n) {
Calendar c = threadCal.get();
c.setTime(this.then):
// use n to mutate c
return c.getTime();
}
}
Run Code Online (Sandbox Code Playgroud)
我这样做是出于正当的原因 - GregorianCalendar
是那些光荣的有状态,可变,非线程安全的对象之一,它提供跨多个调用的服务,而不是表示值.此外,它被认为是"昂贵的"实例化(这是否真实不是这个问题的重点).(总的来说,我真的很佩服它:-))
但是,如果我在任何聚集线程的环境中使用这样的类 - 并且我的应用程序无法控制这些线程的生命周期 - 那么就有可能发生内存泄漏.Servlet环境就是一个很好的例子.
事实上,当一个webapp停止时,Tomcat 7就像这样嘶嘶作响:
严重:Web应用程序[]创建了一个ThreadLocal,其键为[org.apache.xmlbeans.impl.store.CharUtil $ 1](值[org.apache.xmlbeans.impl.store.CharUtil$1@2aace7a7])和一个值类型为[java.lang.ref.SoftReference](值[java.lang.ref.SoftReference@3d9c9ad4]),但在Web应用程序停止时无法将其删除.线程将随着时间的推移而更新,以避免可能的内存泄漏.2012年12月13日下午12:54:30 org.apache.catalina.loader.WebappClassLoader checkThreadLocalMapForLeaks
(在特定情况下,甚至我的代码都没有这样做).
我的多线程概念很薄弱并且正在努力学习.
在我所知道的java中,我们不能再调用一次线程即ie
Thread t = new Thread; //Some Runnable
t.start();
t.start(); //Illegal and throw Exception at runtime.
Run Code Online (Sandbox Code Playgroud)
据我所知,当你再次调用t.start()时会抛出异常,因为一旦它离开t.start()
方法并且你试图再次初始化东西,Thread的相关堆栈就会被销毁.
在这种情况下,我对Threadpool的了解是,它提供了更好的性能并节省了时间,因为不需要创建新线程.(我在http://www.javatpoint.com/thread-pooling-in-java上读到)
如果不需要在ThreadPool场景中创建新的Thread,那么它如何与刚刚完成其run方法的同一个线程一起工作,那么Thread是否可以再次使用?
我读了这篇http://docs.oracle.com/javase/tutorial/essential/concurrency/pools.html ,它说" java.util.concurrent中的大多数执行器实现使用线程池,它由工作线程组成这种线程与它执行的Runnable和Callable任务分开存在,通常用于执行多个任务. "
那么这里的Worker线程是什么,它与普通的Java Threads有什么不同?
使用此链接缓存线程池如何重用现有线程我得到了一些东西但仍然混淆了当我们使用线程池时可以消除哪种东西,并且使用普通Java线程提供更好的性能.
我们可以这样说,
线程有三个部分,
因此,考虑到上述3个步骤,使用Threadpool步骤1和步骤3可以在固定数量的线程创建后消除.只执行每个任务的第2步,这就是为什么Threadpool更快?我们可以这样说吗?我对么?
好吧......我给了网站一个公平的搜索,并阅读了很多关于这个主题的帖子.我发现了这个问题:C#中一个简单线程池的代码特别有用.
但是,总是看起来,我需要的东西略有不同.
我查看了MSDN示例,并根据我的需要进行了调整.我引用的示例如下:http://msdn.microsoft.com/en-us/library/3dasc8as(VS.80,printer).aspx
我的问题是这个.我有一组相当简单的代码,它通过HttpWebRequest
和WebResponse
类加载一个网页,并通过一个来读取结果Stream
.我在一个线程中触发此方法,因为它需要执行多次.该方法本身很短,但需要触发的次数(每次都有不同的数据)会有所不同.它可以是1到200之间的任何地方.
我读过的所有内容似乎都表明ThreadPool
班级是主要候选人.这就是事情变得棘手的事情.我可能需要发出100次这样的事情,但我最多只能运行3个线程(对于这个特定的任务).
我已经尝试设置MaxThreads
上ThreadPool
通过:
ThreadPool.SetMaxThreads(3, 3);
Run Code Online (Sandbox Code Playgroud)
我并不完全相信这种方法有效.此外,我不想破坏将在其上运行的系统上运行的其他网站或程序.因此,通过限制线程的#ThreadPool
,我可以确定这仅适用于我的代码和我的线程吗?
MSDN示例使用事件驱动方法和调用WaitHandle.WaitAll(doneEvents);
,这就是我这样做的方式.
所以我的问题的核心是,如何确保或指定可以为其代码运行的最大线程数,但让代码继续运行更多线程,因为之前的线程完成直到任意点?我是以正确的方式解决这个问题吗?
此致
贾森
好的,我添加了一个信号量方法并完全删除了ThreadPool
代码.看起来很简单.我从http://www.albahari.com/threading/part2.aspx获取了我的信息
这个例子向我展示了如何:
[此处的文字是网站的复制/粘贴]
Semaphore
容量为1的A 类似于a Mutex
或lock
,除了Semaphore
没有"所有者" - 它与线程无关.任何线程都可以调用Release
a Semaphore
,而使用Mutex
和lock
,只有获得资源的线程才能释放它.
在下面的示例中,十个线程执行一个循环,Sleep
中间有一个语句.A Semaphore
确保一次不超过三个线程可以执行该Sleep
语句:
class SemaphoreTest
{
static Semaphore s = new Semaphore(3, 3); // Available=3; Capacity=3 …
Run Code Online (Sandbox Code Playgroud) 您建议在C中使用pthreads线程池进行哪些开源实现?
如果此实现是:
Java 5引入了Executor框架形式的线程池对异步任务执行的支持,其核心是java.util.concurrent.ThreadPoolExecutor实现的线程池.Java 7以java.util.concurrent.ForkJoinPool的形式添加了一个备用线程池.
查看各自的API,ForkJoinPool在标准场景中提供了ThreadPoolExecutor功能的超集(虽然严格来说ThreadPoolExecutor提供了比ForkJoinPool更多的调优机会).除此之外,fork/join任务看起来更快(可能是因为工作窃取调度程序)的观察结果显然需要更少的线程(由于非阻塞连接操作),可能会让人觉得ThreadPoolExecutor已被取代ForkJoinPool.
但这真的是对的吗?我读过的所有材料似乎总结为两种类型的线程池之间相当模糊的区别:
这种区别是否正确?我们能说出更具体的内容吗?
java parallel-processing threadpool threadpoolexecutor forkjoinpool
我有一个使用Executor
框架的Java应用程序,我有这样的代码
protected ScheduledExecutorService scheduledExecutorService = new ScheduledThreadPoolExecutor(5)
我的理解是,JVM内部将创建一个包含5个线程的池.现在,当我在一个分析器中检查执行时,我会得到类似的东西thread-pool2,thread-pool3
等等.
Some of these thread pools are created by the server and some are created by me
,我需要一种方法来区分由我创建的和由服务器创建的.
我想如果我可以命名线程池它应该做的伎俩,但是没有看到任何API允许我这样做.
提前致谢.
我们在Android中执行AsyncTask的正常方式是,从Android API:
private class DoIntenseTask extends AsyncTask<Object, Object, Void> {
protected Void doInBackground(Object... params) {
for (Object param : params) {
Object rtnObj = doIntenseJob(param);
publishProgress(rtnObj);
}
return null;
}
protected void onProgressUpdate(Object... progress) {
for (Object rtnObj : progress) {
updateActivityUI(rtnObj);
}
}
}
Run Code Online (Sandbox Code Playgroud)
我的紧张任务是松散耦合的,执行顺序并不重要,通过这种方式,分配一个线程来运行一系列紧张的任务.我个人认为这是一种中途解决方案.是的,紧张的工作不再在UI线程中运行,但仍然需要逐个执行(在很多情况下,我们面临着一份紧张的工作列表,我认为这也是为什么AsyncTask中的方法是多参数化的原因).谷歌应该使API更具可重用性,以解决不同类型的场景.
我真正喜欢的是由线程池(例如poolSize = 5)并行运行多个doIntenseJob().看起来google确实通过AsyncTask.executeOnExecutor()提供了一个解决方案,但遗憾的是,自API级别11以来才可用.我正在开发移动应用程序,并想知道是否有一个解决方法,我可以在API级别11下实现相同的行为.
在此先感谢
Y.
multiprocessing.Pool
让我疯了......
我想要升级许多软件包,对于每一个软件包,我都要检查是否有更大的版本.这是由该check_one
功能完成的.
主要代码在Updater.update
方法中:我创建了Pool对象并调用该map()
方法.
这是代码:
def check_one(args):
res, total, package, version = args
i = res.qsize()
logger.info('\r[{0:.1%} - {1}, {2} / {3}]',
i / float(total), package, i, total, addn=False)
try:
json = PyPIJson(package).retrieve()
new_version = Version(json['info']['version'])
except Exception as e:
logger.error('Error: Failed to fetch data for {0} ({1})', package, e)
return
if new_version > version:
res.put_nowait((package, version, new_version, json))
class Updater(FileManager):
# __init__ and other methods...
def update(self):
logger.info('Searching for updates')
packages = Queue.Queue() …
Run Code Online (Sandbox Code Playgroud) threadpool ×10
java ×6
concurrency ×2
android ×1
boost ×1
boost-thread ×1
c ×1
c# ×1
c#-2.0 ×1
c++ ×1
forkjoinpool ×1
open-source ×1
pickle ×1
pthreads ×1
python ×1
thread-local ×1