主函数test(int i) 其中i取值1~100 
单线程执行占用30%的CPU我想只同时运行两个线程,保证CPU占用大部分
比如起始开启
test(1)
test(2)
当上面两个线程任意一个执行完毕后再开启test(3)能做到吗?
起始就是如何判断线程结束,结束后开启下一个线程。最好能给出伪代码。。

解决方案 »

  1.   

    自己写的线程函数什么时候结束自己不知道?test2结尾写一个开test3不就好了?
      

  2.   

    如果可能是test1比test2先执行完呢?连续写test1,test2,test3是依次执行,是单线程的
      

  3.   

    很简单,用Semaphore同步对象就可以解决,在所有线程开始前,创建一个全局变量Semaphore,指定资源数等于2,Semaphore _sem=new Semaphore(0,2);然后线程内部,一开始就调用_sem.WaitOne,如果有两个以上县城调用了这个方法就会被阻塞,县城内部处理完之后,调用_sem.Release,就可以了,
      

  4.   

    Semaphore _sem = new Semaphore(0, 2);
            void stocks(object o)
            {
                for (int i = 0; i < 10; i++)
                {
                    Console.Write(o.ToString().PadLeft(3, '0')+" - "+i.ToString() + "\r\n");
                    Thread.Sleep(1000);
                }
            }
            private void button1_Click(object sender, EventArgs e)
            {
                Thread[] threads = new Thread[300];
                for (int i = 0; i < 100; i++)
                {
                    _sem.WaitOne();
                    threads[i] = new Thread(stocks);
                    threads[i].Name = "线程" + i.ToString() ;
                    threads[i].Start(i);
                    _sem.Release();
                }
            }错那了?
      

  5.   


    使用计数信号量Semaphore,是一个比较妥当的同步编程方法,推荐这样实现多个线程的同步。
      

  6.   


    你标题有可能误导出什么Semaphore来。按照你的描述,你要求控制先后执行次序,这只需要使用一个变量去标记是否调用过test3就好了,例如可以写:private object Test3Flag = (bool)false;void CheckCallTest3()
    {
        lock (Test3Flag)
        {
            if ((bool)Test3Flag == false)
            {
                Test3Flag = true;
                test3();
            }
        }
    }这个程序中关键的地方看来你的问题中根本没有涉及。其实会不会口口声声要“多线程”这不算什么,使用lock也不算什么困难的“线程同步”写法,我更加赞同#1楼的问题角度,许多时候简单出发点才是真,那些堆砌技术的反而经常把系统搞到万劫不复的地步。按照你的逻辑就可以肯简单地考虑到,上面这个程序其实也看出来了,你何必要“开启”什么test3?它原本就是使用其中一个已经开启的线程来继续执行的,也就是在test1或者test2执行完毕之后继续执行的。
      

  7.   

    sp1234用了同步锁略复杂了点.而且同步锁是比较慢的.
    就这种情况,用个int之类的做标志用互锁操作比较好,性能更高而且代码简单:
    int test3Flag = 0;
    void test3(){
        if (Interlocked.Exchange(ref test3Flag,1) > 0)
               return;
        //TODO: DO Test3...
    }void test1(){
        //DO test1
        test3();
    }
    void test2(){
        //DO test2
        test3();
    }
      

  8.   

    复杂我倒是没有看出来。就逻辑来说,是调用程序来决定是否要让.net去执行调用test3的一连串操作,可并不是test3自己决定自己是否被调用的。
      

  9.   

    至于效率,要知道Interlocked需要为数值加一或者减一,并且要保证是上锁的操作,同时你还要判断是否>0。我很怀疑,说它会比设置一个bool值然后判断true而性能更高的根据在实际运行机制呢?还是测试呢?
      

  10.   

    说它效率高我想可能是基于它是调用c++方法而不是.net实现的缘故。这个就跟这里没有太多关系了,这就好象你下楼是先迈左脚还是先迈右脚才能最快地走到楼下的问题一样,这里没有必要去研究。楼主的问题的陈述方式会误导出什么Semaphore来,这是明显的逻辑问题。它的三个方法test1、test2、test3是独立的,根本不考虑所谓相互协调问题。它现在需要的是另外一个主程序,首先调用test1和test2,然后来判断是否调用test3,这是需求的逻辑。这个次序问题不去在代码中反映,那么堆砌什么线程同步技术就是多余的,是不按照需求来编程序的。
      

  11.   

    先说对比的问题.在x86平台上bool和int有什么区别呢?lock实质上是调用了Enter/Exit 其实现无非3种:
    1.临界区.
    2.自旋锁.
    3.内核对象/但我想M$不至于这么蛋疼.这三种随便一种和单纯互锁操作的效率查查就知道.最后,你用了object.每次还要装箱/拆箱.这也是要开销的.最后的最后.
    其实那点性能开销基本可以54,
    我就是看两行就搞定的东西多写了那么多行蛋疼....
      

  12.   

                for (int value = 0, index = 2; index != 0; --index)
                {
                    new Thread(new ThreadStart(() =>
                    {
                        for (int i = Interlocked.Increment(ref value); i <= 100; i = Interlocked.Increment(ref value))
                        {
                            test(i);
                        }
                    })).Start();
                }
      

  13.   

    不要在button_click里面调用_sem.WaitOne/Release,应该放在线程里,也就是stocks方法里调用_sem.WaitOne/Release,