线程池与BlockingCollection(Thread Pool with BlockingCollection)
问题:有多个线程访问资源。 我需要限制他们的数量为恒定的
MaxThreads
。 无法进入线程池的线程应该收到错误消息。解决方案:我开始在下面的算法中使用
BlockingCollection<string> pool
,但我看到BlockingCollection
需要调用CompleteAdding
,这是我无法做到的,因为我总是得到传入的线程(我在下面的示例中硬编码为10)调试目的),请考虑Web请求。public class MyTest { private const int MaxThreads = 3; private BlockingCollection<string> pool; public MyTest() { pool = new BlockingCollection<string>(MaxThreads); } public void Go() { var addSuccess = this.pool.TryAdd(string.Format("thread ID#{0}", Thread.CurrentThread.ManagedThreadId)); if (!addSuccess) Console.WriteLine(string.Format("thread ID#{0}", Thread.CurrentThread.ManagedThreadId)); Console.WriteLine(string.Format("Adding thread ID#{0}", Thread.CurrentThread.ManagedThreadId)); Console.WriteLine(string.Format("Pool size: {0}", pool.Count)); // simulate work Thread.Sleep(1000); Console.WriteLine("Thread ID#{0} " + Thread.CurrentThread.ManagedThreadId + " is done doing work."); string val; var takeSuccess = this.pool.TryTake(out val); if (!takeSuccess) Console.WriteLine(string.Format("Failed to take out thread ID#{0}", Thread.CurrentThread.ManagedThreadId)); Console.WriteLine("Taking out " + val); Console.WriteLine(string.Format("Pool size: {0}", pool.Count)); Console.WriteLine(Environment.NewLine); } } static void Main() { var t = new MyTest(); Parallel.For(0, 10, x => t.Go()); }
关于如何更好地实现这一点的任何想法?
谢谢!
PS多线程新手在这里,如果你有任何阅读材料的建议,我将不胜感激他们。
LE:基于我得到的答案,我能够使用这种算法实现期望的行为:
public class MyTest { private const int MaxThreads = 3; private SemaphoreSlim semaphore; public MyTest() { semaphore = new SemaphoreSlim(MaxThreads, MaxThreads); } public void Go() { Console.WriteLine(string.Format("In comes thread ID#{0}", Thread.CurrentThread.ManagedThreadId)); semaphore.Wait(); try { Console.WriteLine(string.Format("Serving thread ID#{0}", Thread.CurrentThread.ManagedThreadId)); // simulate work Thread.Sleep(1000); Console.WriteLine(string.Format("Out goes thread ID#{0}", Thread.CurrentThread.ManagedThreadId)); } finally { semaphore.Release(); } } } static void Main() { var t = new MyTest(); Parallel.For(0, 10, x=> t.Go()); }
Problem: There are multiple threads accessing a resource. I need to limit their number to a constant
MaxThreads
. Threads who cannot enter the thread pool should get an error message.Solution: I started using a
BlockingCollection<string> pool
in the algorithm below, but I see thatBlockingCollection
requires a call toCompleteAdding
, which I can't do, because I always get incoming threads (I hardcoded to 10 in the example below for debugging purposes), think web requests.public class MyTest { private const int MaxThreads = 3; private BlockingCollection<string> pool; public MyTest() { pool = new BlockingCollection<string>(MaxThreads); } public void Go() { var addSuccess = this.pool.TryAdd(string.Format("thread ID#{0}", Thread.CurrentThread.ManagedThreadId)); if (!addSuccess) Console.WriteLine(string.Format("thread ID#{0}", Thread.CurrentThread.ManagedThreadId)); Console.WriteLine(string.Format("Adding thread ID#{0}", Thread.CurrentThread.ManagedThreadId)); Console.WriteLine(string.Format("Pool size: {0}", pool.Count)); // simulate work Thread.Sleep(1000); Console.WriteLine("Thread ID#{0} " + Thread.CurrentThread.ManagedThreadId + " is done doing work."); string val; var takeSuccess = this.pool.TryTake(out val); if (!takeSuccess) Console.WriteLine(string.Format("Failed to take out thread ID#{0}", Thread.CurrentThread.ManagedThreadId)); Console.WriteLine("Taking out " + val); Console.WriteLine(string.Format("Pool size: {0}", pool.Count)); Console.WriteLine(Environment.NewLine); } } static void Main() { var t = new MyTest(); Parallel.For(0, 10, x => t.Go()); }
Any ideas on how I can better achieve this?
Thanks!
P.S. Multi-threading newbie here, if you have any suggestions for reading materials, I would greatly appreciate them.
LE: Based on the answers I got, I was able to achieve the desired behavior using this algorithm:
public class MyTest { private const int MaxThreads = 3; private SemaphoreSlim semaphore; public MyTest() { semaphore = new SemaphoreSlim(MaxThreads, MaxThreads); } public void Go() { Console.WriteLine(string.Format("In comes thread ID#{0}", Thread.CurrentThread.ManagedThreadId)); semaphore.Wait(); try { Console.WriteLine(string.Format("Serving thread ID#{0}", Thread.CurrentThread.ManagedThreadId)); // simulate work Thread.Sleep(1000); Console.WriteLine(string.Format("Out goes thread ID#{0}", Thread.CurrentThread.ManagedThreadId)); } finally { semaphore.Release(); } } } static void Main() { var t = new MyTest(); Parallel.For(0, 10, x=> t.Go()); }
原文:https://stackoverflow.com/questions/26099488
最满意答案
您需要加入
qcat
表才能qcat
表中的其他列进行排序。 尝试这个:$query = " SELECT q.id question_id, q.*, c.* FROM question q INNER JOIN qcat c ON c.category = q.category WHERE q.survey_name='$_SESSION[ssn_sname]' AND c.client_name = '$_SESSION[ssn_sname]' AND q.status='1' AND q.survey_name like '%$sname%' GROUP BY q.id ORDER BY c.p_order LIMIT $start, $limit";
注意:您的查询容易受到SQL注入攻击!
You need to join with the
qcat
table in order to be able to sort on a different column within that table. Try this:$query = " SELECT q.id question_id, q.*, c.* FROM question q INNER JOIN qcat c ON c.category = q.category WHERE q.survey_name='$_SESSION[ssn_sname]' AND c.client_name = '$_SESSION[ssn_sname]' AND q.status='1' AND q.survey_name like '%$sname%' GROUP BY q.id ORDER BY c.p_order LIMIT $start, $limit";
Note: Your query is vulnerable to SQL Injection!
相关问答
更多-
除非您包含明确的order by否则不应该依赖查询结果的排序。 在您的情况下,结果按字母顺序排列(因为group by )。 你可以通过添加: order by max([DateStamp]) 到查询。 You should never rely on the ordering of results from a query unless you include an explicit order by. In your case, the results are ordered by the colu ...
-
订购所有查询(Order all queries)[2021-03-25]
(不确定为什么每个人都在评论中回答而不是“回答”?) 从DB返回结果的顺序完全取决于您告诉它们返回的顺序。 所以,如果你想按时间顺序排列它们,那就不要按名称命名它们; 按时间顺序排列。 因此,不要获取user1的消息,然后获取user2的消息,只需按会话顺序获取整个会话的消息。 然后当你输出它们时,看看哪个用户做了哪个评论并做了“你”/“朋友”的事情。 也就是说,我认为你采取的方法并不理想。 你或许应该做的是在消息发生时逐步获取消息,而不是等待获取所有消息(如果你明白我的意思)。 因此,在每个人的UI上获取 ... -
你可以像这样在你的订单中使用case语句 ORDER BY CASE WHEN ticket_priority_id = 'ASAP' THEN 1 WHEN ticket_priority_id = 'HIGH' THEN 2 WHEN ticket_priority_id = 'MED' THEN 3 WHEN ticket_priority_id = 'LOW' THEN 4 ELSE 5 END You can use ...
-
我想你需要试试这个 $timelineFeed = SoccerMatchTimeline::where('soccer_match_id',$id) ->orderBy('minute', 'DESC') ->orderBy('created_at', 'desc')->get(); 既然你已经提到过,你需要先从一分钟然后从created_at进行排序 I think you need to try this $timelineFeed = SoccerMatchTime ...
-
是的,您只需将sort参数设置为field-name Yes, you just have to set the sort parameter to field-name
-
我们在谈论什么样的收藏? 一个List
? ICollection ? 阵列? 集合中存储的类型是什么? 假设一个List ,你可以这样做: List str = new List (); // add strings to str str.Sort(StringComparer.CurrentCulture); What sort of collections are we talking about? A List ? IColle ... -
子查询按顺序排列(sub queries order by)[2022-06-25]
您需要加入qcat表才能qcat表中的其他列进行排序。 尝试这个: $query = " SELECT q.id question_id, q.*, c.* FROM question q INNER JOIN qcat c ON c.category = q.category WHERE q.survey_name='$_SESSION[ssn_sname]' AND c.client_name = '$_SESSION[ssn_sname]' AND q.status=' ... -
你想要第一个表格: CREATE INDEX example_index ON example_table (a, b, c, d, e); 如果必须扫描整个索引以找到WHERE子句过滤器感兴趣的行,则索引首先按所需的输出顺序排序是没有意义的。 You want the first form: CREATE INDEX example_index ON example_table (a, b, c, d, e); There's no point in the index first being sor ...
-
这就是我要做的事情: #app/models/project.rb Class Project < ActiveRecord::Base has_many :relationshipfollows, :foreign_key => "follower_id", :dependent => :destroy has_many :followers, :through => :relationshipfollows, :source => :follower scope :sor ...
-
query_posts( array( 'post__in' => array( 53,51,46,44,42,40,34,30,28), 'orderby' => 'ID', 'order' => 'DESC' ) ); MySQL不关心查询的IN语句中的元素顺序。 query_posts( array( 'post__in' => array( 53,51,46,44,42,40,34,30,28), ...