У меня есть программа (C#) со списком тестов, чтобы сделать.
Кроме того, я имею два, распараллеливают. один для добавления задачи в список, и один, чтобы читать и удалить из него выполненные задачи.
Я использую функцию 'блокировки' каждый раз, когда один из потоков хочет получить доступ к списку.
Другая вещь, которую я хочу сделать, если список будет пуст, то поток, кто должен читать из списка, будет спать. и проснитесь, когда первый поток добавит задачу к списку. Вот код, который я написал:
...
List<String> myList = new List();
Thread writeThread, readThread;
writeThread = new Thread(write);
writeThread.Start();
readThraed = new Thread(read);
readThread.Start();
...
private void write()
{
while(...)
{
...
lock(myList)
{
myList.Add(...);
}
...
if (!readThread.IsAlive)
{
readThraed = new Thread(read);
readThread.Start();
}
...
}
...
}
private void read()
{
bool noMoreTasks = false;
while (!noMoreTasks)
{
lock (MyList)//syncronize with the ADD func.
{
if (dataFromClientList.Count > 0)
{
String task = myList.First();
myList.Remove(task);
}
else
{
noMoreTasks = true;
}
}
...
}
readThread.Abort();
}
По-видимому, я сделал это неправильно, и это не выполняется как ожидалось (readTread не читает из списка).
Кто-либо знает то, что моя проблема, и как сделать ее правом?
Большое спасибо,
Что вам нужно, так это очередь на блокировку. Это похоже на обычную очередь, за исключением того, что метод Dequeue блокирует, если в очереди ничего нет. Здесь - одна реализация. Как только вы реализуете блокирующую очередь, все остальное станет проще. Просто будьте осторожны, какую реализацию блокирующей очереди вы используете. Я видел много примеров, в которых есть тонкие проблемы с потоками. Возможно, лучше будет придерживаться предоставленной мной ссылки.
public class Example
{
private BlockingQueue<Task> m_Queue = new BlockingQueue<Task>();
public void StartExample()
{
Thread producer = new Thread(() => Producer());
Thread consumer = new Thread(() => Consumer());
producer.Start();
consumer.Start();
producer.Join();
consumer.Join();
}
private void Producer()
{
for (int i = 0; i < 10; i++)
{
m_Queue.Enqueue(new Task());
}
}
private void Consumer()
{
while (true)
{
Task task = m_Queue.Dequeue();
}
}
}
Я бы посоветовал вам взглянуть на пример Джона Скита Producer Consumer . Для получения дополнительной информации о Producer Потребитель, ознакомьтесь с Википедией