首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >线程同步

线程同步
EN

Stack Overflow用户
提问于 2010-06-22 13:19:26
回答 4查看 236关注 0票数 1
代码语言:javascript
复制
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace ThreadDemo
{
    class Program
    {
        static public  List<int> temp = new List<int >();
        static  public  List<Thread> worker = new List<Thread>();
        static public List<List<int>> Temporary = new List<List<int>>();
        static void Main(string[] args)
        {
            temp.add(20);
            temp.add(10);
            temp.add(5);
            foreach (int k in temp)
            {
                int z = 0;
                worker[z] = new Thread(() => { sample(k); });
                worker[z].Name = "Worker" + z.ToString();
                worker[z].Start();
                z++;
            }
        }
        public static void sample(int n)
        {
            List<int> local = new List<int>();
            for (int i = 0; i < n; i++)
            {
                local.Add(i);
            }
            Temporary.Add(local);
        }
    }
}

在这个程序中,我遇到了线程的问题,在启动时,主程序中的foreach循环创建了三个线程,同时也启动了thread.In,第一个线程的操作时间比其他线程长,所以需要一些时间,但是其他线程在第一个线程之前完成的操作,由于这个顺序在临时改变了,.i需要与临时列表一样的临时列表顺序,order.how可以使用线程来实现这一点

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2010-06-22 14:03:53

下面是您的代码的简单介绍:

代码语言:javascript
复制
class Program
{
    static public List<int> temp = new List<int >();
    static public List<Thread> worker = new List<Thread>();
    static public List<List<int>> temporary = new List<List<int>>();
    static public object sync = new object();

    static void Main(string[] args)
    {
        temp.add(20);
        temp.add(10);
        temp.add(5);

        // Add a corresponding number of lists
        for( int i = 0; i < temp.Count; ++i)
        {
            temporary.Add(new List<int>);
        }

        // As Jon Skeet mentioned, z must be declared outside the for loop
        int z = 0;
        foreach (int k in temp)
        {
            // As Jon Skeet mentioned, you need to capture the value of k
            int copy = k;

            Thread t = new Thread(() => { Sample(copy, z); });
            t.Name = "Worker" + z.ToString();

            // set the thread to background, so your thread is 
            // properly closed when your application closes.
            t.IsBackground = true; 
            t.Start();

            // Calling worker[z] will always going to be out of bounds
            // because you didn't add anything to to the worker list,
            // therefore you just need to add the thread to the worker
            // list. Note that you're not doing anything with the worker
            // list, so you might as well not have it at all.
            worker.Add(t);
            z++;
        }
    }

    // Supply the order of your array
    public static void Sample(int n, int order)
    { 
        for (int i = 0; i < n; i++)
        {
            // Technically in this particular case you don't need to 
            // synchronize, but it doesn't hurt to know how to do it.
            lock(sync)
            {
                temporary[order].Add(i);
            }
        }
}

现在,临时列表应该以正确的顺序包含其他列表(与您的tmp顺序相同)。你的标题确实提到了调度,但我不确定为什么你需要在这里调度,或者你到底想学习什么关于调度。

票数 2
EN

Stack Overflow用户

发布于 2010-06-22 13:26:46

有三个问题。首先,变量捕获:

代码语言:javascript
复制
foreach (int k in temp)
{
    int z = 0;
    worker[z] = new Thread(() => { sample(k); });
    ...
}

这捕获了lambda表达式中的变量k,而不是k的值。解决方案是复制一份:

代码语言:javascript
复制
foreach (int k in temp)
{
    int z = 0;
    int copy = k;
    worker[z] = new Thread(() => { sample(copy); });
    ...
}

有关详细信息,请参阅Eric Lippert's blog post

其次,您总是填充worker[0],因为z将始终为0。如果你想填充其他元素,你需要在外部声明z。或者,您也可以直接添加到列表中。

第三,不知道结果的顺序的问题。解决这个问题的最简单方法实际上是将Temporary转换为数组。同样,捕获变量的副本以保持正确的位置。正如ArsenMkrt所说,您还需要更新一个列表,这将涉及到锁定。

你使用的是.NET 4.0吗(或者你可以)?并行扩展使这一切变得非常非常简单。

票数 8
EN

Stack Overflow用户

发布于 2010-06-22 13:25:05

首先,你的所有线程都是访问临时集合,因为列表不是线程安全的,所以你应该同步你的线程才能正常工作,第二,你不能保证如果第一个线程先启动,第一个线程会第一个完成,这取决于内核如何调度线程。要实现您想要的功能,可以使用线程synchronization mechanisms

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3090472

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档