#c #multithreading #qt #wrapper
#c #многопоточность #qt #оболочка
Вопрос:
Я написал некоторый библиотечный код (на C), чтобы облегчить создание и запросы потоков, независимых от платформы. Вот пример псевдокода API для создания потока:
result OS_createThread (
pointer to thread handle (set after thread is created),
stack size,
function to run,
pointer to parameters,
priority )
В зависимости от платформы, я использую соответствующий файл c, который содержит конкретную реализацию ОС, чтобы запустить поток. Например.
result OS_createThread (
// Windows implementation
map priority to Windows priority
// Use Win32 threading call
CreateThread(blah blah)
Я создал порты для Win32, потоков POSIX и некоторых RTOS, которые я использовал. Теперь мне нужно сделать это для среды Qt, и я немного в тупике. Во-первых, я новичок в Qt, во-вторых, похоже, что для этого потребуется объектно-ориентированный подход с использованием класса QThread.
Смысл этого в том, чтобы скрыть суть создания потока от вызывающего абонента. Вызывающий хочет иметь возможность запускать потоки и поддерживать дескриптор этого потока, чтобы он мог что-то делать в будущем, например, изменять его приоритет или уничтожать его.
Используя QThreads, нужно ли создавать новый объект QThread каждый раз, когда запрашивается новый поток? Имейте в виду, что вызывающий код не может иметь ничего специфичного для Qt.
Любые рекомендации приветствуются!
Ответ №1:
Чтобы создать QThread, вы должны реализовать класс, наследуемый от QThread. Пример взят из документации QT
class MyThread : public QThread
{
public:
void run();
};
void MyThread::run()
{
QTcpSocket socket;
// connect QTcpSocket's signals somewhere meaningful
...
socket.connectToHost(hostName, portNumber);
exec();
}
И скрытый в вашей реализации будет:
result OS_createThread (
pointer to thread handle (set after thread is created),
stack size,
function to run,
pointer to parameters,
priority )
{
MyThread *thread = new MyThread(size, function, parameters, prio);
thread->start();
return thread;
}
Таким образом, ваш метод интерфейса C создаст экземпляр такого класса для каждого запрашиваемого потока. Затем этот класс должен хранить все соответствующие данные, переданные из вашей функции, в своих переменных-членах. Функция потока, которая должна быть выполнена, будет вызываться внутри run()
метода. Поскольку вы, кажется, выполняете только методы C, я не вижу проблем с сохранением указателя на них в переменной класса (пожалуйста, поправьте меня, если я ошибаюсь — еще не пробовал ;).
Однако на самом деле это немного сложнее, потому что кому-то придется освободить память, созданную для thread
переменной. И это нелегко (из интерфейса C) в моем примере. Поэтому вы можете подумать об использовании внутреннего класса manager или чего-то, что обрабатывает созданные потоки и уничтожает их по мере необходимости. Однако для того, чтобы сделать квалифицированное заявление о том, как вы могли бы этого добиться, мне понадобится немного больше информации 😉
Комментарии:
1. Наследование от QThread — не лучшая практика для создания потоков в Qt после версии 4.4. Обратите внимание, что даже документация Qt не обновлена. В блоге разработчиков qt есть очень хорошая статья о наилучшем способе реализации потоков в Qt.
2. хороший момент, о котором я не знал, так что спасибо за подсказку. однако основной принцип ответа должен оставаться неизменным. поэтому придерживайтесь новых соглашений и соответствующим образом реализуйте оболочку.
3. Красивые. Чтобы позаботиться об остановке потоков и освобождении памяти, существует также API-функция OS_destroyThread(). Для этого требуется дескриптор потока. Я просто привожу дескриптор к указателю типа «MyThread», вызываю terminate(), wait(), а затем «удаляю» указатель. Это убивает поток и очищает память. Спасибо за помощь!
Ответ №2:
Если вызывающий код не зависит от Qt, почему вы хотите использовать или внедрять QThread-ы?
Если ваша цель — перенести QThread-ы (на самом деле, библиотеку QCore) в вашу странную операционную систему, я бы сначала подробно изучил, как они это реализовали над Pthreads (предполагая, что вы уже хорошо знаете детали потоков posix).
Комментарии:
1. Мой код необходимо перенести в приложение Qt. Эта часть находится вне моего контроля. Мой код в значительной степени является стандартным ANSI C, и единственными вещами, зависящими от платформы, являются потоки, мьютексы и т. Д. Итак, мне нужно написать этот слой-оболочку. Я понимаю, что я не могу просто создавать pthreads (это будет работать в Linux) в приложении Qt.
2. QThread — это вещи C . Вам нужно изучить C , чтобы использовать их. И я не уверен, что вы не можете использовать pthread-ы из кода, использующего Qt. Я попробую сначала, прежде чем переносить ваш glue на QThread-s.