【问题标题】:How wait all thread如何等待所有线程
【发布时间】:2013-07-01 22:30:34
【问题描述】:

我有创建 5 个线程的代码。我需要等待,直到所有线程完成工作,然后返回值。我该怎么做?

public static int num=-1;

public int GetValue()
{
    Thread t=null;
    for (int i = 0; i <=5; i++)
    {
        t = new Thread(() => PasswdThread(i));
        t.Start();  
    }

    //how wait all thread, and than return value?   
    return num;
}

public void PasswdThread(int i)
{
    Thread.Sleep(1000);
    Random r=new Random();
    int n=r.Next(10);
    if (n==5)
    {
        num=r.Next(1000);
    }
}

当然,这不是真正的代码。实际代码要复杂得多,所以我简化了。

附:仔细看。 我没有使用Task,所以不能使用方法Wait() 或WaitAll()。我也不能使用 Join(),因为 Join 等待一个线程。如果他们启动已经完成工作的等待线程,则将无限等待。

【问题讨论】:

标签: c# multithreading


【解决方案1】:

如下创建一个线程数组并调用WaitAll函数

List<Thread> threads = new List<Thread>();
Thread thread = null;
 for (int i = 0; i <=5; i++)
 {
     t = new Thread(() => PasswdThread(i));
     t.Start();
     threads.add(t);
 }
Thread.WaitAll(thread);
 //how wait all thread, and than return value?  
 return num;

【讨论】:

【解决方案2】:

为每个线程创建一个ManualResetEvent 句柄,然后在主线程中调用WaitHandle.WaitAll(handles)

static WaitHandle[] handles = new WaitHandle[5];

`

public void PasswdThread(int i)
{
handles[i] = new ManualResetEvent(false);

 Thread.Sleep(1000);
 Random r=new Random();
 int n=r.Next(10);
 if (n==5)
 {
     num=r.Next(1000);
 }
 handles[i].Set();
}

获取更多关于http://msdn.microsoft.com/en-us/library/z6w25xa6.aspx的信息

【讨论】:

  • 与其拥有 n 个 MRE,不如将一个信号量初始化为 N;它会更简单。虽然只使用Thread.JoinThread.WaitAll 可能会更简单。
【解决方案3】:

我认为你可以使用Thread.WaitAll(thread_array),或者在其他情况下你也可以使用Thread.Sleep(100)

Thread.sleep 中,100 是毫秒数。所以在这种情况下线程会休眠 100 毫秒。

Thread.WaitAll - thread_Array 中是您想要等待的线程数组。

【讨论】:

  • 真正的软件没有Sleep()。它当然不能替代加入/等待。
【解决方案4】:

由于这个问题实际上是重复的,请参阅this answer,(代码复制如下,全部归功于 Reed Copsey。

class Program
{
    static void Main(string[] args)
    {
        int numThreads = 10;
        ManualResetEvent resetEvent = new ManualResetEvent(false);
        int toProcess = numThreads;

        // Start workers.
        for (int i = 0; i < numThreads; i++)
        {
            new Thread(delegate()
            {
                Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
                // If we're the last thread, signal
                if (Interlocked.Decrement(ref toProcess) == 0)
                    resetEvent.Set();
            }).Start();
        }

        // Wait for workers.
        resetEvent.WaitOne();
        Console.WriteLine("Finished.");
    }
}

一边

另请注意,您的PasswdThread 代码不会产生随机数。 Random 对象应在您的方法之外静态声明,以生成随机数。

此外,您从不使用该方法的int i 参数。

【讨论】:

    【解决方案5】:

    我会为此使用 TPL,我认为它是处理这种同步的最新技术。鉴于现实生活中的代码可能更复杂,我将稍微修改示例:

    public int GetValue()
    {
        List<Task<int>> tasks = new List<Task<int>>();
        for (int i = 0; i <=5; i++)
        {
            tasks.Add(PasswdThread(i));
        }
    
        Task.WaitAll(tasks);
    
        // You can now query all the tasks:
        foreach (int result in tasks.Select(t => t.Result))
        { 
            if (result == 100) // Do something to pick the desired result...
            {
                return result;
            }
        }
    
        return -1;
    }
    
    public Task<int> PasswdThread(int i)
    {
        return Task.Factory.StartNew(() => {
            Thread.Sleep(1000);
            Random r=new Random();
            int n=r.Next(10);
            if (n==5)
            {
                return r.Next(1000);
            }
            return 0;
        });
    }
    

    【讨论】:

    • 不!我不能使用任务,因为从线程写入文件有很多问题。
    【解决方案6】:
        Thread t=null;
    List<Thread> lst = new List<Thread();
        for (int i = 0; i <=5; i++)
        {
             t = new Thread(() => PasswdThread(i));
             lst.Add(t);
             t.Start();  
        }
    
        //how wait all thread, and than return value?   
    foreach(var item in lst)
    {
        while(item.IsAlive)
        {
             Thread.Sleep(5);
        }
    }
        return num;
    

    【讨论】:

    • 你不应该使用busywait;有提供给您的工具可以避免不必要地消耗如此多的额外资源。
    猜你喜欢
    • 1970-01-01
    • 2021-11-03
    • 2016-11-05
    • 1970-01-01
    • 1970-01-01
    • 2012-07-22
    • 1970-01-01
    • 2010-09-20
    • 1970-01-01
    相关资源
    最近更新 更多