Моя очередь ведет себя забавно, есть идеи, почему? - PullRequest
1 голос
/ 17 октября 2010

Я хотел провести некоторое тестирование с очередями и использовать Queue.Synchronized, чтобы увидеть, как это работает, когда два потока помещают данные в очередь, а третий поток читает их.Это казалось довольно простым, но это не работает правильно, и я не уверен, почему.Вероятно, глупая ошибка с моей стороны.Хотя есть кое-что еще.

class Program
{
    public int this1 = 0;
    static void Main(string[] args)
    {
        Tester test1 = new Tester();

        Queue myQ = new Queue();
        Tester.myQ = Queue.Synchronized(myQ);
        Thread test1_thread = new Thread(new ThreadStart(test1.test1));
        Thread test1_thread2 = new Thread(new ThreadStart(test1.test1));

        test1_thread.Start();
        test1_thread2.Start();

        int i = 0;
        while (i <= 10)
        {

            i++;
        go_back_here:
            try
            {
                Tester.myQ.Enqueue(40);
                Console.WriteLine("did it");
                int holding = Convert.ToInt32(Tester.myQ.Dequeue());
                Console.WriteLine("reading out {0}: {1}", i);
            }
            catch
            {
                //Console.Write("e");
                //goto go_back_here;
            }
        }
        Console.ReadLine();
    }


}

class Tester
{

    public static Queue myQ;
    public void test1()
    {
        int this1 = 0;

        while (this1 <= 10)
        {
            Console.WriteLine("Doing something {0}", this1);
            myQ.Enqueue(this1);
            Console.WriteLine("(peek) {0}", myQ.Dequeue());
            this1++;
        }

    }
}

Благодаря моему собственному тестированию я обнаружил, что два потока тестера нормально загружают вещи в очередь.Когда мой основной цикл пытался удалить его из очереди, я получал сообщение о том, что очередь пуста.Я вставлял peeks, а затем Dequeues в потоки тестирования, и они смогли нормально показать содержимое потока.

Затем я подумал, получаю ли я каким-то образом доступ к неправильной очереди из основного цикла (OOP не моя сильная сторонаеще учусь), поэтому я добавил «Tester.myQ.Enqueue (40);»чтобы посмотреть, смогу ли я что-нибудь в нее вставить.Мои peeks / Dequeues не показывали это, но оно обнаружилось, когда я добавил строку для записи "did it".Я запускал программу очень много раз, и 40 из основного цикла появлялись только при печати потоков тестирования из Dequeue, когда «сделал это».Никогда, когда я это закомментирую.

Может ли кто-то более осведомленный в этом вопросе пролить свет на то, что происходит?(и да, я знаю, что использование goto - ужасная вещь, я позволил ей сдвинуться с места, потому что это должен был быть простой тест)

1 Ответ

2 голосов
/ 17 октября 2010

Похоже, что ваша первоначальная проблема заключалась в том, что ваш основной поток слишком быстро получал доступ к очереди (в ней ничего нет, потому что потоки начали что-то добавлять в нее одновременно). Вам нужно будет убедиться, что потоки закончили работать, прежде чем читать из очереди в основном потоке. Вы можете ждать их, вызывая Thread.Join или, альтернативно, Thread.Sleep, входя в цикл, проверяя состояние некоторой глобальной переменной, установленной потоками. Недостаточно иметь цикл while без сна или присоединения.

Кроме того, ваш «взгляд» на самом деле не взгляд, потому что он фактически удаляет элемент. Вам нужно использовать Console.WriteLine("(peek) {0}", myQ.Peek()); вместо myQ.Dequeue().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...