创建新线程或为线程获取更多工作
我正在创建一个程序(用 C# 编写),我看到两种方法。1
)一个作业管理器等待任意数量的 X 线程完成,完成后它会获取下一个工作块并创建一个新的工作块线程并给它该块
或
2)我们创建X个线程来启动,给它们每个工作块,当一个线程完成一个块时,它会要求作业管理器做更多的工作。 如果没有更多的工作,它就会睡觉,然后再次询问,睡眠时间逐渐变长。
这个程序将运行并完成,但我可以看到它变成一个不断寻找更多工作的服务。
每个块将由许多数据id组成,调用数据库以获取一些信息或对数据id执行操作,然后将数据id上的信息写入数据库。
I've got a program I'm creating(in C#) and I see two approaches..
1) A job manager that waits for any number of X threads to finish, when finished it gets the next chunk of work and creates a new thread and gives it that chunk
or
2) We create X threads to start, give them each a chunk of work, and when a thread finishes a chunk its asks the job manager for more work. If there isn't any more work it sleeps and then asks again, with the sleep becoming progressively longer.
This program will be a run and done, tho I could see it turning into a service that continually looks for more jobs.
Each chunk will consists of a number of data ids, a call to the database to get some info or perform an operation on the data id, and then writing to the database info on the data id.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
假设您知道处理多线程数据库操作时需要采取额外的预防措施,听起来您正在描述两种不同的场景。 首先,您有多个线程正在运行,一旦所有线程都完成,它将寻找新的工作。 在第二种情况下,您有多个线程正在运行,并且它们的操作是完全并行的。 您的环境将决定采取正确的方法; 如果有一些东西将所有工作捆绑在多个线程中,并且在所有线程完成之前无法继续其他工作,则使用前者。 如果彼此没有太大影响,就选择后者。
Assuming you are aware of the additional precautions that need to be taken when dealing with multithreaded database operations, it sounds like you're describing two different scenarios. In the first, you have several threads running, and once ALL of them finish it will look for new work. In the second, you have several threads running and their operations are completely parallel. Your environment is going to be what determines the proper approach to take; if there is something tying all of the work in the several threads where additional work cannot continue until all of them are finished, then with the former. If they don't have much affect on each other, go with the latter.
第二个选项并不正确,因为使睡眠时间逐渐变长意味着您将不必要地阻塞这些线程。
相反,您应该像第二个选项一样拥有一组线程池,但它们使用 WaitHandles 来等待工作并使用生产者/消费者模式。 基本上,当生产者指示有工作时,它会向消费者发送一个信号(将有一个管理器来确定哪个线程将获得工作,然后向该线程发出信号),该信号将唤醒并开始工作。
您可能想查看并行任务库。 它现在处于测试阶段,但如果您可以使用它并且对它感到满意,我会推荐它,因为它将为您管理大量内容(而且更好的是,考虑到机器上的核心数量,最佳线程数等)。
The second option isn't really right, as making the sleep time progressively longer means that you will unnecessarily keep those threads blocked.
Rather, you should have a pooled set of threads like the second option, but they use WaitHandles to wait for work and use a producer/consumer pattern. Basically, when the producer indicates that there is work, it sends a signal to a consumer (there will be a manager which will determine which thread will get the work, and then signal that thread) which will wake up and start working.
You might want to look into the Parallel Task Library. It's in beta now, but if you can use it and are comfortable with it, I would recommend it, as it will manage a great deal of this for you (and much better, taking into account the number of cores on a machine, the optimal number of threads, etc, etc).
前一种解决方案(为每个新工作生成一个线程)更容易编码,而且如果工作单元足够大的话也不会太糟糕。
第二种解决方案(线程池,带有工作队列)的代码更复杂,但支持更小的工作单元。
The former solution (spawn a thread for each new piece of work), is easier to code, and not too bad, if the units of work are large enough.
The second solution (thread-pool, with a queue of work), is more complicated to code, but supports smaller units of work.
您应该查看 .NET 框架中的 ThreadPool 类,而不是滚动自己的解决方案。 您可以使用
QueueUserWorkItem
方法。 它应该完全符合您想要完成的任务。Instead of rolling your own solution, you should look at the
ThreadPool
class in the .NET framework. You could use theQueueUserWorkItem
method. It should do exactly what you want to accomplish.