除了下面这个,还有其它方法吗?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace ThreadsBlock
{
class Program
{
static void Main(string[] args)
{
AutoResetEvent mre = new AutoResetEvent(false);
Thread t1 = new Thread(() => ConsoleAtoE(mre));
Thread t2 = new Thread(() => Console1to5(mre));
t1.Start();
t2.Start();
}
static void ConsoleAtoE(AutoResetEvent mre)
{
string str = "ABCDE";
for (int i = 0; i < str.Length; i++)
{
Console.Write(str[i]);
mre.WaitOne();
}
}
static void Console1to5(AutoResetEvent mre)
{
string str = "12345";
for (int i = 0; i < str.Length; i++)
{
Console.Write(str[i]);
mre.Set();
Thread.Sleep(1);
}
}
}
}
去看一下线程交互吧 不推荐这种做法
这种写法 确认可以每次都打印出 A1B2C3D4E5 ?
用两个阻塞队列 BlockingCollection(1), 一个存字符 一个存数字, 同时消费
可以用两个信号量来处理
class Program
{
static Semaphore toLetter = new Semaphore(0, 1);
static Semaphore toNumber = new Semaphore(0, 1);
static void Main(string[] args)
{
var threadLetter = new Thread(PrintLetter);
var threadNumber = new Thread(PrintNumber);
threadLetter.Start();
threadNumber.Start();
}
static void PrintLetter()
{
var letters = "ABCDE";
for (int i = 0; i < letters.Length; i++)
{
if (i != 0)
{
toLetter.WaitOne();
}
Console.Write(letters[i]);
toNumber.Release();
}
}
static void PrintNumber()
{
var numbers = "12345";
for (int i = 0; i < numbers.Length; i++)
{
toNumber.WaitOne();
Console.Write(numbers[i]);
if (i != numbers.Length - 1)
{
toLetter.Release();
}
}
}
}
老铁666啊!!!
两个信号量都为互斥信号量,且初始状态的信号量可用为0(即为无效状态, 最大可用信号量为1),此时WatiOne时会阻塞当前线程的执行,一直等到对应的信号量Release之后,它的WaitOne(而此时信号量又回归初始的状态,可用为0,最大可用信号量为1)方法才会通过继续执行下面的代码。
不知使用一个互斥信号量能不能完成呢?
不知以上我对于信号量的理解正确与否?
@沉默的虾米活跃的鱼: 是的理解是对的,这是基于操作系统底层信号量机制的,很多语言都有具体的实现类。上面那种解决方案因为需要两个线程相互有顺序的输出,使用一个信号量是没办法保证交替顺序的。其实这一题是我之前面试正好碰见的,原题是: 如何使Go的两个协程交替输出1-100,看起来很眼熟就随手写了一版