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