Хобрук: Ваш путь к мастерству в программировании

Функция ZeroMQ Kill Thread

Я создаю проект, используя ZeroMQ. Мне нужны функции для запуска и завершения потока. Функция запуска работает нормально, но есть проблемы с функцией остановки.

private Thread _workerThread;
private object _locker = new object();
private bool _stop = false;

public void Start()
    {
        _workerThread = new Thread(RunZeroMqServer);
        _workerThread.Start();
    }

    public void Stop()
    {
        lock (_locker)
        {
            _stop = true;
        }

        _workerThread.Join();
        Console.WriteLine(_workerThread.ThreadState);
    }

    private void RunZeroMqServer()
    {
        using (var context = ZmqContext.Create())
        using (ZmqSocket server = context.CreateSocket(SocketType.REP))
        {
            /*
            var bindingAddress = new StringBuilder("tcp://");
            bindingAddress.Append(_ipAddress);
            bindingAddress.Append(":");
            bindingAddress.Append(_port);
            server.Bind(bindingAddress.ToString());
            */

            //server.Bind("tcp://192.168.0.102:50000");
            server.Bind("tcp://*:12345");

            while (!_stop)
            {
                string message = server.Receive(Encoding.Unicode);
                if (message == null) continue;

                var response = ProcessMessage(message);
                server.Send(response, Encoding.Unicode);

                Thread.Sleep(100);
            }
        }
    }

Может быть, кто-то знает об этой функции Stop(), почему она не убивает поток? Мне подсказали, что я должен использовать Thread.MemoryBarrier и volatile, но понятия не имею, как это должно работать. Так же есть функция ProcessMessage() для обработки сообщений, просто не стал копировать, чтобы не мусорить :)

21.06.2014

Ответы:


1

Похоже, проблема в том, что вы вызываете блокирующую версию ZmqSocket.Receive. Пока он ожидает получения сообщения, он не обрабатывает остальную часть вашего кода, поэтому он никогда не попадает в условие цикла.

Решение состоит в том, чтобы использовать один из неблокирующих методов или тот, который имеет тайм-аут. Попробуй это:

string message = server.Receive(Encoding.Unicode, TimeSpan.FromMilliseconds(100));

Это должно вернуться через 100 мс, если сообщение не получено, или раньше, если сообщение получено. В любом случае он получит шанс на состояние цикла.


Что касается самого флага _stop...

Когда вы получаете доступ к переменным из нескольких потоков, блокировка является хорошей идеей. Однако в случае простого флага и чтение, и запись являются в значительной степени атомарными операциями. В этом случае достаточно объявить его как volatile (private volatile bool _stop = false;), чтобы сообщить компилятору, что он всегда действительно считывает текущее значение каждый раз, когда вы ему это указываете.

21.06.2014
Новые материалы

Понимание СТРУКТУРЫ ДАННЫХ И АЛГОРИТМА.
Что такое структуры данных и алгоритмы? Термин «структура данных» используется для описания того, как данные хранятся, а алгоритм используется для описания того, как данные сжимаются. И данные, и..

Как интегрировать модель машинного обучения на ios с помощью CoreMl
С выпуском новых функций, таких как CoreML, которые упростили преобразование модели машинного обучения в модель coreML. Доступная модель машинного обучения, которую можно преобразовать в модель..

Создание успешной организации по науке о данных
"Рабочие часы" Создание успешной организации по науке о данных Как создать эффективную группу по анализу данных! Введение Это обзорная статья о том, как создать эффективную группу по..

Технологии и проблемы будущей работы
Изучение преимуществ и недостатков технологий в образовании В быстро меняющемся мире технологии являются решающим фактором в формировании будущего работы. Многие отрасли уже были..

Игорь Минар из Google приедет на #ReactiveConf2017
Мы рады сообщить еще одну замечательную новость: один из самых востребованных спикеров приезжает в Братиславу на ReactiveConf 2017 ! Возможно, нет двух других кланов разработчиков с более..

Я собираюсь научить вас Python шаг за шагом
Привет, уважаемый энтузиаст Python! 👋 Готовы погрузиться в мир Python? Сегодня я приготовил для вас кое-что интересное, что сделает ваше путешествие более приятным, чем шарик мороженого в..

Альтернатива шаблону исходящих сообщений для архитектуры микросервисов
Познакомьтесь с двухэтапным сообщением В этой статье предлагается альтернативный шаблон для папки Исходящие : двухэтапное сообщение. Он основан не на очереди сообщений, а на..