无法在线程运行方法中运行CryptoPP FileSink的情况下终止Qt线程

Cannot kill Qt thread with CryptoPP FileSink running in the thread run method

本文关键字:运行 线程 情况下 Qt FileSink 终止 方法 CryptoPP      更新时间:2023-10-16

我在C++和QT5.4中有一个UI应用程序,我使用CryptoPP 5.6.2加密文件。我遇到了以下问题:

  1. 点击"加密"按钮时,将根据本教程启动一个新线程。

    // new thread
    CryptoWorkerThread = new QThread;
    this->worker = new CryptoWorker(fileName.c_str(), newFileName.c_str(), key, keyLength, iv);
    this->worker->moveToThread(CryptoWorkerThread);
    connect(worker, SIGNAL(error(QString)), this, SLOT(errorString(QString)));
    connect(CryptoWorkerThread, SIGNAL(started()), worker, SLOT(process()));
    connect(worker, SIGNAL(finished()), CryptoWorkerThread, SLOT(quit()));
    connect(worker, SIGNAL(finished()), this, SLOT(on_CryptoWorker_finished()));
    connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater()));
    connect(CryptoWorkerThread, SIGNAL(finished()), CryptoWorkerThread, SLOT(deleteLater()));
    CryptoWorkerThread->start();
    
  2. 我将指向线程和工作线程的指针存储在主窗口类中(加密按钮的父级,从而存储插槽)

    工人阶级:

    class CryptoWorker : public QObject {
    Q_OBJECT
    public:
    CryptoWorker(const char* sourceFileName, const char* destFileName, const byte * key, int keyLength, const byte * iv);
    ~CryptoWorker();
    const char* sourceFileName;
    const char* destFileName;
    public slots:
    void process();
    signals:
    void finished();
    void error(QString err);
    private:
    // add your variables here
    const byte* key;
    const byte* iv;
    int keyLength;
    };
    CryptoWorker::CryptoWorker(const char* sourceFileName, const char* destFileName, const byte * key, int keyLength, const byte * iv){
    this->sourceFileName = sourceFileName;
    this->destFileName = destFileName;
    this->key = key;
    this->keyLength = keyLength;
    this->iv = iv;
    }
    CryptoWorker::~CryptoWorker(){
    }
    void CryptoWorker::process(){
    CryptoPP::CBC_Mode<CryptoPP::AES>::Encryption encryptor(key, keyLength, iv);
    
    CryptoPP::FileSource(sourceFileName, true,
    new CryptoPP::StreamTransformationFilter(
    encryptor,
    new CryptoPP::FileSink(destFileName),
    CryptoPP::BlockPaddingSchemeDef::PKCS_PADDING
    ),
    true // StreamTransformationFilter
    ); // FileSource
    emit finished();
    return;
    }
    

现在,当线程运行时,我正在使用以下函数将文件A加密到文件B:

CryptoPP::FileSource(sourceFileName, true,
new CryptoPP::StreamTransformationFilter(
encryptor,
new CryptoPP::FileSink(destFileName),
CryptoPP::BlockPaddingSchemeDef::PKCS_PADDING
),
true // StreamTransformationFilter
); // FileSource

但是,线程会被卡住,直到文件完成编码和写入,这可能需要几分钟的时间。我没有办法杀死线程,因为没有地方放isAlive()检查。

我正在努力寻找一个解决方案,允许我使用FileSource、FileSink(与fstream、file或qfile相比速度惊人),并允许我在某个时候取消操作。

我通过添加另一个线程来检查新创建的加密文件B的大小,解决了进度监控问题,但控制在给定时刻写入的字节会很酷(这样我就可以检查isAlive()并增加数据计数器)。

在这一点上,我陷入了困境,无法找到解决方案。请帮忙。

您可以尝试将false传递给FileSource构造函数的第二个参数(pumpAll),并使用Pump方法在块中进行循环工作-这应该允许检查isAlive并增加计数器。