Как создать оболочку потока Qt

#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.