1. 软件初始化的时候,需要连接硬件,连接硬件必须放在一个线程里,因为主界面会很卡,但是放在线程里电机连打开成功后,关闭程序关闭电机连接的时候会报VC++ Runtime Library Error。电机的API都由电机厂家提供。如果打开连接放在主线程里,关闭程序关闭电机连接就没有问题。要避免这个错误,是否是关闭连接也放在和打开连接的一个线程里???但是初始化成功后这个线程还处于运行状态的话,其它操作硬件的工作线程跑起来就会卡,所以想让它处于阻塞状态,等关闭程序的时候给它发消息,让它激活,再关闭连接。这样该怎么做比较好啊?
2.程序里启动一个外部程序,当它接收图像实时显示图像的时候,启动程序里一个硬件操作,硬件操作也放在一个线程里,结果两边都卡,接收图像的程序图像不刷新,内存不断累积;硬件运行的也卡。如果不显示图像,硬件运行就不卡。本来程序运行的时候占用的CPU就比较多,所以想在启动硬件线程的时候先让其它线程阻塞,硬件操作完后,再唤醒其它线程。
C#里线程的操作不像JAVA里那么多,比如wait,notify,suspend,resume已经过时,因为有死锁倾向,用Join的话是否可以?“在当前线程中调用另一个线程的join()方法,则当前线程转入阻塞状态,直到另一个进程运行结束,当前线程再由阻塞转为就绪状态。”我觉得不像用suspend,resume那么方便或者是否还有其它方法?多线程 线程等待

解决方案 »

  1.   

    启动工作中,就开启一个线程,然后waitone,或者开启线程后面什么都不要写,在线程中,通过委托告诉主界面,执行完毕,然后去做其他的事情
      

  2.   

    我就知道join,c#里面还有个类可以做到忘了叫什么名字
      

  3.   

    Suspend()直接挂起,需要时Resume()唤醒
      

  4.   

    用信号量Semaphore,后台线程中release,主线程中waitone
      

  5.   

    电机连接线程里用ManualRestEvent,电机连接成功后让通知主线程,保存ManualRestEvent对象,然后ManualRestEvent就wait,要关闭的时候就用保存的ManualRestEvent对象激活电机连接线程就可以了。
      

  6.   

    第二个问题。道理一样的啊。ManualRestEvent控制线程激活还是阻塞。
      

  7.   

    其他的问题看看一些书就可以了,即使这里回答了,你也要花时间去研究。关于VC++ Runtime Library Error,一般是你在线程里做了非法内存操作,仔细看自己的代码,肯定有的!
      

  8.   

    C#中的信号量(Semaphore)机制信 号量也算是个鼎鼎大名的东西吧,提到互斥量总会说起信号量。二者的差别很简单,互斥量、临界区是用于保护“一个”需要被互斥访问的资源,这个资源同时只有 一个线程能被访问;而信号量可以被用于管理“资源池”。在.Net中Semaphore类就是对Windows信号量的封装。
    Semaphore有着一些我们已经知道的特性: * 你可以创建没有名称的“局部”信号量,也可以创建命名的“全局”信号量用于跨应用程序域的同步。
    * 你可以用WaitOne()请求一个资源。
    * 你需要使用try/finally结构调用“Close()”,确保信号量资源在使用后被正确释放。
    * 你仍然需要注意在全局情况下Semaphore的访问安全问题。  总的来说,Semaphore与Mutex更像是兄弟,仍然与EventWaitHandle一脉不太亲近: * Semaphore从机制上来说跟Mutex一样属于“锁”而不是“通知”,因此跟Mutex一样几乎没有“通知”的能力。
    * 举个不恰当但是很形象的例子,Semaphore就是一个可以多次进入的“Mutex”。Mutex永远只允许一个线程拥有它,而 Semaphore可以允许多个线程请求,因此Semaphore被用于管理一次可以允许多个线程进入并发访问资源的情况。之所以说“不恰当”,是因为一 旦允许多个线程访问资源,那么这时候的资源一定不是互斥资源,相应的代码段也不再是“临界区”。
    * 因为Semaphore与Mutex在请求数量上的不同,因此他们的线程相关性是不同的。这一点,Semaphore到跟 EventWaitHandle一样,它是线程无关的。也就是说对Semaphore地释放者可以不定是Semaphore的拥有者。比如说我可以是消费 者线程总使用WaitOne()请求线程池中的资源从来不需要释放,而生产者总是Release线程池中的资源而从来不请求。
    * Semaphore使用Release()来表示对资源的释放,不过与ReleaseMutex()不同,这个函数有重载方法允许你指定释放几个资源。这引发了一个问题,如果Release的次数超过资源总量,那么会引发SemaphoreFullException异常。 比如线程A和线程B都进入信号量。如果线程B中发生了一个编程错误,导致它调用Release()两次(或者Release(2)),则两次调用都会成 功。这样,信号量的计数就已经达到了最大值,所以,当线程A最终调用Release时将引发异常。这相当于本来资源中只有N个资源,最后却有超过N个资源 被还回来。
    * 记得使用完以后调用Close()释放信号量资源。看过一段对于信号量的介绍,有一个最生动的比喻:信号量其实就好比有一个公共资源,要想访问,必须要获得授权证。信号量里面有两个记 录,分别记录目前可以发放的授权证书数量和总共的授权书数量。信号量的定义Semaphore(int initialCount, int MaximumCount),其中initialCount就是说明目前可以发放多少个授权证,而参数maximumCount则是限制总共有多少个授权 证。当然,获得授权证的使用后,就有权限访问资源,但是,在访问完成后,必须要归还授权证才行。归还后,信号量里的“目前可以发放的授权证书数量”便会增 加相应的个数。
    下面贴出来MSDN上的一段示例代码,分析一下信号量
    using System;
    using System.Threading;
    public class Example
    {
        // A semaphore that simulates a limited resource pool.
        //
        private static Semaphore _pool;
        // A padding interval to make the output more orderly.
        private static int _padding;
        public static void Main()
        {
            // Create a semaphore that can satisfy up to three
            // concurrent requests. Use an initial count of zero,
            // so that the entire semaphore count is initially
            // owned by the main program thread.
            //
            _pool = new Semaphore(0, 3);
            // Create and start five numbered threads.
            //
            for (int i = 1; i <= 5; i++)
            {
                Thread t = new Thread(new ParameterizedThreadStart(Worker));
                // Start the thread, passing the number.
                //
                t.Start(i);
            }
            // Wait for half a second, to allow all the
            // threads to start and to block on the semaphore.
            //
            Thread.Sleep(500);
            // The main thread starts out holding the entire
            // semaphore count. Calling Release(3) brings the
            // semaphore count back to its maximum value, and
            // allows the waiting threads to enter the semaphore,
            // up to three at a time.
            //
            Console.WriteLine("Main thread calls Release(3).");
            _pool.Release(3);
            Console.WriteLine("Main thread exits.");
            Console.Read();
        }
        private static void Worker(object num)
        {
            // Each worker thread begins by requesting the
            // semaphore.
            Console.WriteLine("Thread {0} begins " +
                "and waits for the semaphore.", num);
            _pool.WaitOne();
            // A padding interval to make the output more orderly.
            int padding = Interlocked.Add(ref _padding, 100);
            Console.WriteLine("Thread {0} enters the semaphore.", num);
            // The thread's "work" consists of sleeping for
            // about a second. Each thread "works" a little
            // longer, just to make the output more orderly.
            //
            Thread.Sleep(1000 + padding);
            Console.WriteLine("Thread {0} releases the semaphore.", num);
            Console.WriteLine("Thread {0} previous semaphore count: {1}",
                num, _pool.Release());
            Console.WriteLine("Thread {0} Finished", num);
        }
    }
    在这段代码中,Main函数初始化信号量(0,3),表示:目前可以发放的授权证书数量是0,授权证书总共有3个。在Main函数调用Release(3)方法归还了授权证书后,其他等待的线程才可以获得授权并运行。
    为了展现一下上面提到的SemaphoreFullException,可以把代码稍微改一下,比如,把信号量初始化时,改成如下:
                   _pool = new Semaphore(1, 3);
    再次运行程序后,便会出现如下问题:
         向信号量添加给定计数将导致其超出它的最大计数。
    这个错误是怎么出现的呢??
    分析一下运行步骤就知道了:
    (1)、信号量被初始化为(1,3),此时,信号量中可以发出的授权证数目是1
    (2)、Thread1获得授权证书。后,信号量可以发出的授权证数目是0。而此时,Thread2/3/4/5都处于等待状态。
    (3)、Main函数使用Release(3),归还给信号量3个授权证书。此时信号量可以发放的授权证数目是3。
    (4)、Thread2/3/4获得授权证书。后,信号量可以发出的授权证数目是0,此时Thread5继续处于等待状态
    (5)、Thread1运行完毕,归还一个授权证。此时信号量可发放授权证书是1
    (6)、Thread5获得授权证书。后,信号量可以发出的授权证数目是0。
    (7)、Thread2/3/4运行完毕,分别归还授权证,此时信号量可发放证书数目是3,已经达到了初始化时规定的最大数量
    (8)、Thread5运行完毕,归还授权证书,此时信号量可发放证书数目再次加一时,便超出了规定最大数目,出现了Exception。
    呵呵,对于信号量的初始化和Release确实需要小心对待的。
      

  9.   

    我用ManualRestEvent和waitOne实现的。