gpt4 book ai didi

c# - 如何顺序访问每个线程中的列表元素

转载 作者:太空狗 更新时间:2023-10-29 18:35:19 25 4
gpt4 key购买 nike

最近我在电话采访中被问到这个问题

“假设有 3 个长度相同的数组列表 l1、l2 和 l3。 三个线程访问三个列表。 说 T1 -> l1,T2 -> l2 & T3 -> l3。 它应该按第一个列表的第一个元素然后第二个列表的第一个元素然后第三个列表的第一个元素的顺序打印。然后是第一个列表的第二个元素,然后是第二个列表的第二个元素,然后是第三个列表的第二个元素。”

我回答说使用信号量可以解决这个问题,但是当我尝试使用信号量时无法得到正确的答案。我下面的代码有什么问题

namespace Semaphore_Example
{
class Program
{
static List<int> list1 = new List<int>{ 1, 2, 3, 4, 5 };
static List<int> list2 = new List<int> { 1, 2, 3, 4, 5 };
static List<int> list3 = new List<int> { 1, 2, 3, 4, 5 };

static Semaphore semaphore = new Semaphore(0,3);
static SemaphoreSlim _sem = new SemaphoreSlim(3);

static void Main(string[] args)
{

Thread t1 = new Thread(show);
Thread t2 = new Thread(show);
Thread t3 = new Thread(show);

t1.Start();
t2.Start();
t3.Start();

Console.ReadLine();
}

static void show()
{
_sem.Wait();

for (int i = 0; i < 5; i++)
{
Console.WriteLine(list1[i]);
Console.WriteLine(list2[i]);
Console.WriteLine(list3[i]);
}

_sem.Release();

}
}
}

最佳答案

信号量本身不适合您的要求。信号量可以同步对给定资源的访问,但它不维护尝试访问它的线程之间的顺序。每MSDN :

There is no guaranteed order, such as FIFO or LIFO, in which blocked threads enter the semaphore.

相反,我建议您使用一组等待句柄,每个线程一个,这样每个线程在打印每个元素之前都在自己的句柄上等待,并在完成后向下一个线程的句柄发出信号。下面的示例被概括为适用于任意数量的列表(线程)。

static List<string> list1 = new List<string> { "A1", "A2", "A3", "A4", "A5" };
static List<string> list2 = new List<string> { "B1", "B2", "B3", "B4", "B5" };
static List<string> list3 = new List<string> { "C1", "C2", "C3", "C4", "C5" };

// Add all lists to the array below.
static List<string>[] lists = new[] { list1, list2, list3 };
static AutoResetEvent[] waitHandles;

static void Main(string[] args)
{
waitHandles = new AutoResetEvent[lists.Length];
var threads = new Thread[lists.Length];

for (int i = 0; i < lists.Length; i++)
{
// Initialize a wait handle and thread for each list.
int threadIndex = i;
waitHandles[i] = new AutoResetEvent(false);
threads[i] = new Thread(new ThreadStart(() => show(threadIndex)));
threads[i].Start();
}

// Signal first thread to start off process.
waitHandles[0].Set();

Console.ReadLine();
}

// Method run within each thread.
static void show(int threadIndex)
{
// The index of the next thread to signal after printing each element.
int nextThreadIndex = (threadIndex + 1) % lists.Length;

// Iterate over all elements of current thread's list.
foreach (string x in lists[threadIndex])
{
// Wait for turn of current thread.
waitHandles[threadIndex].WaitOne();

// Print one element.
Console.Write(x + " ");

// Signal next thread to proceed.
waitHandles[nextThreadIndex].Set();
}

// Assume all lists are equal in length.
// Otherwise, threads might need to keep signalling
// even after printing all their elements.
}

// Output: A1 B1 C1 A2 B2 C2 A3 B3 C3 A4 B4 C4 A5 B5 C5

关于c# - 如何顺序访问每个线程中的列表元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28524785/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com