机器学习和生物信息学实验室论坛联盟MAchine Learning And Bioinformatics, MALAB
查看: 7926|回复: 6

关于多线程及什么时候使用多线程

[复制链接]
发表于 2011-6-29 15:37:42 | 显示全部楼层 |阅读模式
多线程使用System.Threading类

以下是一个例子

class Fibonacci
    {
        //share
        public static int [] item; //read from it
        public static int[] result; //write into it
        //instance
        public int N { get { return _n; } }
        public int _start, _end;
        private int _n;

        public int FibOfN { get { return _fibOfN; } }
        private int _fibOfN;

        private ManualResetEvent _doneEvent;

        public Fibonacci(int start, int end, ManualResetEvent doneEvent)
        {
            _start = start;
            _end = end;
            _doneEvent = doneEvent;
        }

        public Fibonacci(int start, int end)
        {
            _start = start;
            _end = end;
        }

        // Wrapper method for use with thread pool.
        public void ThreadPoolCallback(Object threadContext)
        {
            int threadIndex = (int)threadContext;

            Calculate();

            _doneEvent.Set();
        }

        // Recursive method that calculates the Nth Fibonacci number.
        public void    Calculate()
        {
            for (int i = _start; i < _end; i++)
            {
                int d = item[i];
                for (int j = 0; j < 10000; j++) //注意,这里设置大值使单个线程对单个共享数据的运算时间较大
                    d += 0;
                lock(this) //在本程序中可以不加,因为没有互斥
                      result[i] = d;
            }
        }



    }

    class TestThreading
    {
        public static void test()
        {
            Fibonacci.item = new int[10000];
            Fibonacci.result = new int[10000];
            for (int i = 0; i < 10000; i++)
            {
                Fibonacci.item[i] = i + 1;
               
            }
            Stopwatch watch = new Stopwatch();
            watch.Start();
            Fibonacci f = new Fibonacci(0, 10000);
            f.Calculate();
            watch.Stop();
            Console.WriteLine("Time no thrading takes " + watch.Elapsed);
            Console.ReadLine();
            for (int i = 0; i < 10000; i++)
            {
                Console.Write(Fibonacci.result[i] + " ");
            }
            Console.ReadLine();

            //thread 5
            watch = new Stopwatch();
            watch.Start();
            Fibonacci[] fibarray = new Fibonacci[5];
            ManualResetEvent[] doneEvents = new ManualResetEvent[5];

            for (int i = 0; i < 5; i++)
            {
                int start = i * 2000;
                int end = (i + 1) * 2000;
                doneEvents[i] = new ManualResetEvent(false);
                fibarray [i] = new Fibonacci (start ,end ,doneEvents[i]);
                ThreadPool.QueueUserWorkItem(fibarray[i].ThreadPoolCallback, i);
            }
            WaitHandle.WaitAll(doneEvents);
            watch.Stop();
            Console.WriteLine("Time 5 threads takes " + watch.Elapsed);
            Console.ReadLine();
            for (int i = 0; i < 10000; i++)
            {
                Console.Write(Fibonacci.result[i] + " ");
            }
            Console.ReadLine();

        }
    }


需要注意的一点就是,如果多个线程访问同一个数据效率是没有提升反而因为线程初始化等开销加大
这就是为什么上面的J如果是小的数目,比如5,多线程效率反而不如单线程
回复

使用道具 举报

 楼主| 发表于 2011-6-29 15:38:14 | 显示全部楼层
郁闷,这么说来我的优化过程还是要很长了
回复

使用道具 举报

发表于 2011-6-29 16:33:43 | 显示全部楼层
肯定的啊,
多线程本质上是并行,
斐波那契序列这种问题每一次运算都要用到前一次运算的结果,无法用并行的思想。
多线程应该处理在一堆数中找最大数这类问题,应该有效率;
建议明年去听我讲算法:D
回复

使用道具 举报

发表于 2011-6-29 19:18:01 | 显示全部楼层
对于同一数据操作系统貌似有一个保护机制,在同一时刻只能有一个线程写数据,其他线程只能排队等待,所以不会提高很多。对于可以采用分治方法解决得问题,用多线程效率会提高很多。
回复

使用道具 举报

 楼主| 发表于 2011-6-29 22:27:52 | 显示全部楼层
不知道稀疏矩阵怎么分治...现在做的矩阵分解模型太占内存也太耗时了:(
回复

使用道具 举报

发表于 2012-9-17 11:50:47 | 显示全部楼层
操作系统只能读并行,写串行,这是读写锁的保护机制
回复

使用道具 举报

发表于 2012-9-17 18:46:28 | 显示全部楼层
Orz... 理论与实践并重的达人.
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

关注公众号
机器学习和生物信息学实验室联盟

相关侵权、举报、投诉及建议等,请发 E-mail:admin@discuz.vip

Powered by Discuz! X5.0 © 2001-2026 Discuz! Team.

在本版发帖
关注公众号
返回顶部