Является ли libuv поток безопасным?

Я создал новый поток, посвященный циклу выполнения libuv. Функция потока выглядит примерно так:

void thread_function()
{
uv_loop_t *loop = uv_loop_new();
uv_ref( loop );
uv_run( loop );
}

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

Тем не менее, при проверке uv_ref Исходный код Я не увидел никакой гарантии, что доступ к переменной счетчика ссылок будет синхронизирован во время одновременного доступа. Кроме того, я не видел никаких вызовов yield для передачи управления операционной системе во время цикла выполнения, что означает, что программа не будет хорошо взаимодействовать с другими процессами.

Это заставляет меня поверить, что я не использую libuv правильным образом. Если бы кто-то мог объяснить, что я делаю неправильно, это было бы здорово!

14

Решение

Нет, libuv не является потокобезопасным в этом смысле. Вы должны использовать uv_async, чтобы дать сигнал циклу выйти. uv_async — единственное поточно-ориентированное средство, которое есть в libuv.

Это будет выглядеть примерно так:

uv_async_t exit_handle;

void exit_async_cb(uv_async_t* handle, int status) {
/* After closing the async handle, it will no longer keep the loop alive. */
uv_close((uv_handle_t*) &exit_handle, NULL);
}

void thread_function() {
uv_loop_t *loop = uv_loop_new();
/* The existence of the async handle will keep the loop alive. */
uv_async_init(loop, &exit_handle, exit_async_cb);
uv_run(loop);
}

Теперь из другого потока вы можете дать сигнал этому циклу выйти, вызвав

uv_async_send(&exit_handle);

Вы должны заботиться, чтобы не звонить uv_async_send() до того, как другой поток завершит настройку цикла и дескриптора uv_async. Последние версии libuv включают uv_barrier примитивы синхронизации, которые вы можете использовать; но версия libuv, поставляемая с Node.js 0.8, пока не поддерживает это, поэтому вам, вероятно, нужно использовать средства pthread, чтобы это работало.

На заметку, вы, кажется, звоните uv_ref а также uv_unref со ссылкой на цикл в качестве аргумента. В последних версиях libuv это изменилось, теперь вы должны uv_ref а также uv_unref конкретная ручка. Увидеть uv.h для деталей.

34

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]