Qt 多線程編程:單例任務隊列的設計與實現

引言:

在現代應用程序開發中,多線程編程已成為處理異步任務的標配。對于 GUI 應用而言,保持主線程的響應性尤為重要。本文將詳細介紹一個基于 Qt 的單例任務隊列實現方案,它通過線程池和單例模式,優雅地解決了后臺任務管理的難題。

一、為什么需要任務隊列?

在GUI應用中,我們經常需要執行一些耗時操作,如文件IO、網絡請求、復雜計算等。如果直接在主線程中執行這些操作,會導致界面卡頓甚至無響應。理想的解決方案是將這些任務放到后臺線程中執行。

但簡單地為每個任務創建一個新線程會帶來新的問題:線程創建和銷毀的開銷、線程數量過多導致的資源耗盡、任務執行順序難以控制等。任務隊列正是為解決這些問題而生。

二、核心架構設計

2.1 系統組件概覽

我們的異步處理系統由兩大核心組件構成:

單例任務隊列系統
任務線程 TaskThread
單例模板 Singleton
任務隊列管理
線程同步機制
異常安全處理
線程安全初始化
生命周期管理

2.2 任務隊列線程(TaskThread)

TaskThread是整個系統的異步執行引擎,繼承自Qt的QThread類,負責管理任務隊列和執行任務。

  • 關鍵功能解析:
    1. 任務隊列管理

      • 使用std::deque<TaskItem>存儲任務,支持雙端插入
      • 每個任務包含函數對象和任務類型
      • 任務類型可用于分類管理和批量清除
    2. 任務添加策略

      • immediate參數控制任務插入位置
      • true:插入隊列頭部(高優先級)
      • false:插入隊列尾部(普通優先級)
    3. 線程同步機制

      • QMutex保護共享資源(任務隊列)
      • QWaitCondition實現線程間通信
      • 無任務時線程休眠,有新任務時喚醒
  • 核心實現代碼:
#include <QThread>
#include <QMutex>
#include <QWaitCondition>
#include <deque>
#include <functional>
#include <atomic>
#include <iostream>// 任務類型定義
using TaskType = int;
const TaskType ANY_TASK = -1;// 任務項結構體
struct TaskItem {std::function<void()> func;  // 任務函數TaskType type = 0;           // 任務類型
};// 任務線程類
class TaskThread : public QThread {Q_OBJECT
public:explicit TaskThread(QObject* parent = nullptr) : QThread(parent), stop_flag_(false) {}~TaskThread() override {stop();}// 添加任務到隊列void addTask(std::function<void()> task, TaskType type = 0, bool immediate = false) {QMutexLocker locker(&mtx_condition_);if (stop_flag_) return;if (immediate) {tasks_.emplace_front(TaskItem{std::move(task), type});} else {tasks_.emplace_back(TaskItem{std::move(task), type});}condition_.wakeOne();}// 清除指定類型任務void clearTask(TaskType type = ANY_TASK) {QMutexLocker locker(&mtx_condition_);if (type == ANY_TASK) {tasks_.clear();} else {auto it = tasks_.begin();while (it != tasks_.end()) {if (it->type == type) {it = tasks_.erase(it);} else {++it;}}}}// 停止線程void stop() {{QMutexLocker locker(&mtx_condition_);if (stop_flag_) return;stop_flag_ = true;tasks_.clear();condition_.wakeAll();}wait();}// 啟動線程void active() {start();}signals:void sigGenerateLogReport(const QString& report);protected:void run() override {while (true) {TaskItem task;{QMutexLocker locker(&mtx_condition_);// 等待任務或停止信號while (tasks_.empty() && !stop_flag_) {condition_.wait(&mtx_condition_);}// 檢查退出條件if (stop_flag_ && tasks_.empty()) {return;}// 獲取任務task = std::move(tasks_.front());tasks_.pop_front();}// 執行任務try {if (task.func) task.func();} catch (...) {// 異常處理邏輯std::cerr << "Task execution failed" << std::endl;}}}private:std::deque<TaskItem> tasks_;     // 任務隊列QMutex mtx_condition_;           // 互斥鎖QWaitCondition condition_;       // 條件變量std::atomic_bool stop_flag_;     // 停止標志
};

2.3 單例模板(Singleton)

Singleton模板確保全局只有一個TaskThread實例,提供安全、統一的訪問入口

  • 關鍵技術亮點:
    • 使用互斥鎖保證線程安全
    • 延遲初始化(Lazy Initialization)
    • 提供引用和指針兩種獲取方式
    • 注意避免拷貝構造(必須使用auto&Singleton::instance()
  • 單例實現核心:
// 單例模板
template <typename T>
class Singleton {
public:// 獲取單例引用static T& instance() {std::call_once(init_flag_, []() {instance_ = new T();std::atexit(destroy);});return *instance_;}// 獲取單例指針static T* ptr() {return instance_;}// 判斷是否已銷毀static bool isNull() {return instance_ == nullptr;}// 銷毀單例static void destroy() {if (instance_) {delete instance_;instance_ = nullptr;}}private:Singleton() = delete;~Singleton() = delete;Singleton(const Singleton&) = delete;Singleton& operator=(const Singleton&) = delete;static T* instance_;static std::once_flag init_flag_;
};

2.4 使用示例 (Main)

// 靜態成員初始化
template <typename T>
T* Singleton<T>::instance_ = nullptr;template <typename T>
std::once_flag Singleton<T>::init_flag_;// 使用示例
void addLogGenerationTask() {Singleton<TaskThread>::instance().addTask([] {// 模擬日志生成(實際應用中可能是耗時操作)QString report = "System log report generated at " + QDateTime::currentDateTime().toString();// 通過信號發送結果emit Singleton<TaskThread>::ptr()->sigGenerateLogReport(report);}, 1);  // 類型1表示日志任務
}int main(int argc, char *argv[]) {QCoreApplication app(argc, argv);// 啟動任務線程Singleton<TaskThread>::instance().active();// 添加任務addLogGenerationTask();// 添加立即執行任務Singleton<TaskThread>::instance().addTask([] {std::cout << "Urgent task executed immediately!" << std::endl;}, 0, true);// 清除所有日志任務Singleton<TaskThread>::instance().clearTask(1);// 程序結束時自動停止線程QObject::connect(&app, &QCoreApplication::aboutToQuit, [] {Singleton<TaskThread>::instance().stop();});return app.exec();
}

三、工作原理詳解

3.1 生產者-消費者模型

整個系統基于經典的生產者-消費者模型:

  • 生產者:向任務隊列添加任務的線程(通常是主線程)
  • 消費者TaskThread線程,負責從隊列中取出并執行任務
  • 共享資源:任務隊列std::deque
  • 同步機制QMutexQWaitCondition

這種模型的優勢在于解耦了任務提交和執行,使代碼更易維護和擴展。

3.2 任務執行流程

下面是run()方法的核心邏輯:

void TaskThread::run()
{while (!is_exit_) {QMutexLocker locker(&mtx_condition_);if (tasks_.empty()) {condition_.wait(&mtx_condition_);} else {auto func = tasks_.front().func;if (func) {func();}tasks_.pop_front();}}
}

執行流程:

  1. 線程進入循環,檢查退出標志
  2. 加鎖后檢查隊列是否為空
  3. 隊列為空時調用wait()釋放鎖并休眠
  4. 有新任務時被喚醒,獲取隊首任務執行
  5. 執行完畢后解鎖,繼續循環

3.3 線程同步機制

同步是多線程編程的難點,我們的實現采用了以下策略:

  • 添加任務時

    void TaskThread::addTask(...)
    {QMutexLocker locker(&mtx_condition_);// 添加任務到隊列condition_.wakeAll();
    }
    
  • 清除任務時

    void TaskThread::clearTask(TaskType type)
    {QMutexLocker locker(&mtx_condition_);// 過濾并清除指定類型任務condition_.wakeAll();
    }
    
  • 線程等待時

    condition_.wait(&mtx_condition_);
    

這種設計確保:

  1. 任何時候只有一個線程可以操作任務隊列
  2. 隊列為空時線程不會空轉,節省CPU資源
  3. 新任務添加或隊列變更時,工作線程能及時響應

四、解決的核心痛點

  • 解耦任務提交與執行:業務代碼只需關注任務邏輯,無需關心線程管理
  • 線程資源復用:避免頻繁創建/銷毀線程的開銷
  • 任務優先級控制:支持緊急任務插隊執行
  • 類型化任務管理:可按類型分類和批量清除任務
  • 線程安全:完善的同步機制確保多線程環境下的穩定性

4.1 主線程阻塞問題

在GUI應用中,耗時操作會導致界面凍結無響應。單例任務隊列通過將任務轉移到后臺線程執行,保持界面流暢。

傳統方式

void generateReport() {// 在主線程執行耗時操作QString report = createComplexReport(); // 界面凍結!showReport(report);
}

使用任務隊列

void generateReportAsync() {Singleton<TaskThread>::instance().addTask([] {QString report = createComplexReport();QMetaObject::invokeMethod(qApp, [report] {showReport(report); // 回到主線程更新UI});});
}

4.2 資源競爭與線程安全

多線程環境下,資源競爭是常見問題。我們的方案通過:

  1. 單例模式確保全局唯一訪問點
  2. 互斥鎖保護任務隊列
  3. 條件變量實現高效線程等待

4.3 任務管理混亂

傳統異步代碼常面臨任務管理難題

  • 無法取消已提交任務
  • 缺乏優先級控制
  • 沒有任務分類機制

我們的解決方案提供:

// 添加緊急任務(插隊執行)
addTask(urgentTask, HIGH_PRIORITY, true);// 清除所有日志任務
clearTask(LOG_TASK_TYPE);// 安全停止所有任務
stop();

五、典型應用場景

  • 后臺文件操作:如備份、壓縮、批量重命名等
  • 數據處理:如解析大型JSON/XML文件、統計分析等
  • 網絡任務:如下載文件、同步數據等
  • 定時任務:如定期清理緩存、生成報表等

5.1 后臺日志處理

void logSystemExample() {// 添加日志生成任務Singleton<TaskThread>::instance().addTask([] {// 在后臺線程執行QString logContent = generateSystemLog();saveToFile(logContent);// 通知主線程emit logSaved(logContent);}, LogTask);// 添加緊急日志上傳Singleton<TaskThread>::instance().addTask([] {if (!uploadCriticalLogs()) {retryUpload(); // 自動重試機制}}, CriticalLogTask, true); // 立即執行
}

5.2 數據處理流水線

void dataProcessingPipeline() {// 第一階段:數據清洗(后臺執行)Singleton<TaskThread>::instance().addTask([] {auto data = loadRawData();return cleanData(data);}, DataCleanTask);// 第二階段:數據分析(依賴清洗結果)Singleton<TaskThread>::instance().addTask([] {auto result = analyzeData();emit analysisComplete(result);}, DataAnalysisTask);
}

5.3 定時任務調度

// 創建定時器
QTimer* dailyReportTimer = new QTimer(this);// 每天生成報告
connect(dailyReportTimer, &QTimer::timeout, [] {Singleton<TaskThread>::instance().addTask([] {generateDailyReport();}, ReportTask);
});dailyReportTimer->start(24 * 60 * 60 * 1000); // 24小時

5.4 后臺執行文件備份

在后臺執行文件備份任務,完成后通知主線程更新進度或顯示結果。

// 在主線程中提交備份任務(例如用戶點擊"緊急備份"按鈕后)
Singleton<TaskThread>::instance().addTask([this] {// 源文件路徑與備份路徑QString sourceDir = "/home/user/documents";QString backupDir = "/backup/docs_" + QDateTime::currentDateTime().toString("yyyyMMddHHmmss");// 創建備份目錄QDir().mkpath(backupDir);// 執行文件拷貝(模擬耗時操作)bool success = false;QFileInfoList files = QDir(sourceDir).entryInfoList(QDir::Files);for (const QFileInfo &file : files) {// 檢查是否需要中斷(可根據實際需求添加取消邏輯)if (QThread::currentThread()->isInterruptionRequested()) {success = false;break;}// 拷貝文件success = QFile::copy(file.filePath(), backupDir + "/" + file.fileName());if (!success) break;// 模擬處理延遲QThread::msleep(100);}// 任務完成后通過信號通知主線程emit sigBackupCompleted(success, backupDir);},TaskThread::Other,  // 任務類型:其他類型true);              // 緊急任務,插入隊首優先執行

這個例子展示了幾個關鍵點:

  1. 通過單例模式獲取全局任務隊列實例,無需傳遞線程指針
  2. 使用lambda表達式封裝備份邏輯,包含文件IO等耗時操作
  3. 通過sigBackupCompleted信號將結果(備份是否成功、備份路徑)傳遞給主線程
  4. 設置immediate=true確保緊急備份任務優先執行
  5. 支持任務中斷檢查(通過isInterruptionRequested

六、高級特性與優化策略

6.1 批量任務處理

當任務數量大且執行快時,批量處理可顯著減少鎖競爭:

void run() {const int BATCH_SIZE = 10; // 每次處理10個任務std::vector<TaskItem> batch;while (!stop_flag_) {{QMutexLocker locker(&mtx_condition_);// 批量獲取任務for (int i = 0; i < BATCH_SIZE && !tasks_.empty(); ++i) {batch.push_back(std::move(tasks_.front()));tasks_.pop_front();}}// 批量執行for (auto& task : batch) {task.func();}batch.clear();}
}

6.2 優先級隊列擴展

使用std::priority_queue替代std::deque實現多級優先級

// 任務優先級定義
enum Priority {Immediate,  // 最高優先級High,Normal,Low
};struct TaskItem {std::function<void()> func;Priority priority;
};// 優先隊列比較器
struct TaskCompare {bool operator()(const TaskItem& a, const TaskItem& b) {return a.priority > b.priority; // 值越小優先級越高}
};// 使用優先隊列
std::priority_queue<TaskItem, std::vector<TaskItem>, TaskCompare> tasks_;

6.3 異常安全增強

健壯的異常處理防止單個任務崩潰整個線程:

void run() {while (true) {// ... [獲取任務]try {if (task.func) task.func();} catch (const std::exception& e) {qCritical() << "Task failed:" << e.what();emit taskFailed(task.type, e.what());}catch (...) {qCritical() << "Unknown task error";emit taskFailed(task.type, "Unknown error");}}
}

6.4 任務進度反饋

// 定義帶進度的任務函數
using ProgressFunc = std::function<void(int)>; // 進度回調(0-100)
void addTaskWithProgress(std::function<void(ProgressFunc)> func, ...);// 使用示例
addTaskWithProgress([](ProgressFunc progress) {for (int i = 0; i < 100; ++i) {// 執行部分任務progress(i); // 反饋進度QThread::msleep(50);}
});

七、最佳實踐與注意事項

7.1 生命周期管理

MainThreadSingletonTaskThreadinstance()創建實例addTask()執行任務destroy()stop()停止確認MainThreadSingletonTaskThread

關鍵規則

  1. main函數退出前調用Singleton<TaskThread>::destroy()
  2. 在QApplication析構前停止任務線程
  3. 任務中避免持有界面對象的長期引用

7.2 跨線程通信規范

// 安全更新UI的兩種方式:// 方式1:使用QMetaObject
Singleton<TaskThread>::instance().addTask([] {QString result = processData();QMetaObject::invokeMethod(qApp, [result] {updateUI(result); // 在主線程執行});
});// 方式2:通過信號槽(自動排隊)
class Controller : public QObject {Q_OBJECT
public slots:void handleResult(const QString& result) {updateUI(result);}
};// 在任務中發射信號
emit taskCompleted(result); // 自動跨線程傳遞

7.3 資源清理策略

清理類型選擇

// 清除所有任務
clearTask(ANY_TASK);// 僅清除網絡請求任務
clearTask(NETWORK_TASK);// 清除低優先級任務
clearTask(LOW_PRIORITY_TASK);

八、擴展與未來方向

8.1 線程池集成

對于CPU密集型任務,可擴展為線程池架構

class TaskThreadPool {
public:TaskThreadPool(int size = QThread::idealThreadCount()) {for (int i = 0; i < size; ++i) {auto thread = new TaskThread(this);threads_.push_back(thread);thread->active();}}void addTask(std::function<void()> task, Priority pri = Normal) {// 負載均衡算法選擇線程auto thread = selectThread();thread->addTask(task, pri);}private:std::vector<TaskThread*> threads_;
};

8.2 任務依賴管理

實現有向無環圖(DAG) 管理復雜任務依賴:

數據加載
數據清洗
特征提取
數據驗證
模型訓練

8.3 持久化任務隊列

添加磁盤持久化支持,防止應用崩潰時任務丟失:

void saveQueueToDisk() {QMutexLocker locker(&mtx_condition_);QFile file("task_queue.dat");file.open(QIODevice::WriteOnly);QDataStream out(&file);for (const auto& task : tasks_) {out << task.type;// 序列化任務函數(需要特殊處理)}
}

九、完整實現與使用示例

9.1 基礎用法

// 初始化
Singleton<TaskThread>::instance().active();// 添加普通任務
Singleton<TaskThread>::instance().addTask([] {qDebug() << "Normal task executed";
}, NORMAL_TASK);// 添加緊急任務
Singleton<TaskThread>::instance().addTask([] {qDebug() << "Urgent task executed first!";
}, URGENT_TASK, true);// 清理特定任務
Singleton<TaskThread>::instance().clearTask(NORMAL_TASK);// 安全退出
QCoreApplication::aboutToQuit.connect([] {Singleton<TaskThread>::destroy();
});

9.2 實際應用案例

異步圖片處理

void processImages(const QStringList& imagePaths) {for (const auto& path : imagePaths) {Singleton<TaskThread>::instance().addTask([path] {// 在后臺線程處理QImage image(path);image = applyFilters(image);// 保存處理結果QString outputPath = generateOutputPath(path);image.save(outputPath);// 通知主線程emit imageProcessed(outputPath);}, IMAGE_PROCESSING_TASK);}
}

結語:

單例任務隊列架構通過統一的任務調度中心高效的線程管理,解決了現代應用開發中的關鍵異步處理難題。本文介紹的技術方案具有:

  1. 高可靠性:異常安全處理和線程同步保障
  2. 靈活擴展:支持優先級、批量處理和任務分類
  3. 易于集成:簡潔的API和單例訪問模式
  4. 資源高效:單線程處理大量任務

這種架構特別適合以下場景:

  • GUI應用保持界面響應
  • 服務器應用處理并發請求
  • 數據處理流水線
  • 定時任務調度系統

學習資源:

(1)管理教程
如果您對管理內容感興趣,想要了解管理領域的精髓,掌握實戰中的高效技巧與策略,不妨訪問這個的頁面:

技術管理教程

在這里,您將定期收獲我們精心準備的深度技術管理文章與獨家實戰教程,助力您在管理道路上不斷前行。

(2)軟件工程教程
如果您對軟件工程的基本原理以及它們如何支持敏捷實踐感興趣,不妨訪問這個的頁面:

軟件工程教程

這里不僅涵蓋了理論知識,如需求分析、設計模式、代碼重構等,還包括了實際案例分析,幫助您更好地理解軟件工程原則在現實世界中的運用。通過學習這些內容,您不僅可以提升個人技能,還能為團隊帶來更加高效的工作流程和質量保障。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/88712.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/88712.shtml
英文地址,請注明出處:http://en.pswp.cn/web/88712.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

OpenEuler操作系統中檢測插入的USB設備并自動掛載

OpenEuler操作系統中檢測插入的USB設備并自動掛載 項目需求&#xff1a;工控機上openeuler操作系統是無界面版本的&#xff0c;在工控機上連接了激光雷達&#xff0c;當激光雷達采集完數據&#xff0c;我們要將采集數據導入u盤&#xff0c;故需要在工控機上插入u盤&#xff0c;…

《Spring 中上下文傳遞的那些事兒》Part 11:上下文傳遞最佳實踐總結與架構演進方向

&#x1f4dd; Part 11&#xff1a;上下文傳遞最佳實踐總結與架構演進方向 經過前面幾篇文章的深入探討&#xff0c;我們已經系統性地學習了 Spring 應用中上下文傳遞的各種技術原理、常見問題以及解決方案。從 Web 請求上下文到異步任務、從多租戶隔離到日志脫敏&#xff0c;…

使用云虛擬機搭建hadoop集群環境

使用云虛擬機搭建hadoop集群環境 安裝jdk17 配置docker網絡 docker network create --subnet172.18.0.0/16 hadoop 172.18.0.0&#xff1a;這是子網的網絡地址&#xff0c;也就是這個網絡的起始地址。/16&#xff1a;這是子網掩碼&#xff08;Network Mask&#xff09;&#x…

【機器學習】吳恩達機器學習課程代碼作業-Python版本

吳恩達老師的機器學習課程作業是MATLAB版本&#xff08;Octave&#xff09;的&#xff0c;現在有點過時了&#xff0c;我參考了幾位大牛的代碼&#xff0c;將作業改成了Python3.6版本&#xff0c;并做了中文注釋&#xff0c;推薦使用Jupyter notebook。Python作業使用了原版數據…

2025年人工智能、虛擬現實與交互設計國際學術會議

重要信息 官網&#xff1a;www.aivrid.com 時間&#xff1a;2025年10月17-19日 地點&#xff1a;中國-東莞 部分介紹 征稿主題 包括但不限于&#xff1a; 生物特征 模式識別 機器視覺 專家系統 深度學習 智能搜索 自動編程 智能控制 智能機器…

SHA-256算法流程分析與詳解——Github工程結合示例和動畫演示

近日筆者在學習區塊鏈的相關知識&#xff0c;接觸到SHA-256算法&#xff0c;這里做一個知識梳理和總結。 強烈推薦大家自行去學習下面鏈接github上的工程&#xff0c;作者的動畫演示和解釋做的非常出色&#xff0c;邏輯非常清晰&#xff0c;B站搬運的對應的油管的講解視頻也放…

CSPNet: A New Backbone that can Enhance Learning Capability of CNN (CSP模塊)

3. Method 方法 3.1 Cross Stage Partial Network 跨階段局部網絡 3.1.1 Cross Stage Partial Network 跨階段局部網絡 3.1.1.1 ResNet 和 DenseNet 的優缺點主流的卷積神經網絡&#xff08;CNN&#xff09;架構&#xff0c;如ResNet [8]、ResNeXt [37]、DenseNet [11]&#x…

前端學習4:小白入門注冊表單的制作(包括詳細思考CSS、JS實現過程)

這篇我們來做一個簡單表單&#xff0c;即常見的注冊頁面吧~學習完這篇我們將學習到Input、label、CSS偽類、CSS入門、更多的JS操作等。。一、首先明確需求&#xff1a;直接模仿常見的注冊頁面&#xff0c;包括&#xff1a;用戶名、Email、性別&#xff08;單選按鈕男/女&#x…

強化學習 (RL) 新突破:超越游戲,走向復雜現實決策

強化學習 (RL) 新突破&#xff1a;超越游戲&#xff0c;走向復雜現實決策 強化學習&#xff08;Reinforcement Learning&#xff0c; RL&#xff09;作為人工智能的核心范式之一&#xff0c;歷經數十年的發展&#xff0c;正迎來一場深刻的范式轉移。曾以戰勝人類頂尖選手的Alph…

2025年6-7月AI領域關鍵進展:從藥物研發到全球監管--AI深度融入產業與社會

2025年6月至7月&#xff0c;人工智能領域繼續以驚人速度發展&#xff0c;在技術突破、行業應用、政策法規、企業戰略及學術研究等方面取得了一系列重要里程碑。以下為關鍵動態&#xff1a;一、技術突破&#xff1a; AI向生命科學和認知科學縱深挺進DeepMind啟動AI設計藥物人體試…

【TOOL】ubuntu升級cmake版本

文章目錄一、下載cmake腳本二、安裝一、下載cmake腳本 在編譯新工程時遇到cmake版本過低的情況&#xff0c;到 cmake官網 下載指定cmake安裝腳本&#xff1a; 若需下載指定版本&#xff0c;見上圖右上角藍框。 二、安裝 # 賦予可執行權限 sudo chmod x cmake-3.31.8-linux-x8…

GMSK調制解調系統的matlab性能仿真,對比維特比解調,1bit差分解調,2bit差分解調

目錄 1.前言 2.算法運行效果圖預覽 3.算法運行軟件版本 4.部分核心程序 5.算法仿真參數 6.算法理論概述 7.參考文獻 8.算法完整程序工程 1.前言 GMSK(Gaussian Minimum Shift Keying&#xff0c;高斯最小頻移鍵控)是一種連續相位調制技術&#xff0c;基于MSK調制改進而…

SQL138 連續兩次作答試卷的最大時間窗

SQL138 連續兩次作答試卷的最大時間窗 問題分析 找出2021年至少有兩天作答的用戶計算每個用戶連續兩次作答的最大時間窗基于歷史數據預測在這個時間窗內平均會做多少套試卷 版本1 with-- 功能?&#xff1a;篩選2021年至少有兩天作答的用戶及其作答記錄-- 子查詢找出2021年…

TensorFlow2 study notes[2]

文章目錄tf.autodiff.ForwardAccumulatorreferencestf.autodiff.ForwardAccumulator the function can be used to achieve the Computation of Jacobian-vector products with forward-mode autodiff. primals is variables need to watch.tangents is direction vector. …

穩定幣將成為新時代的重要金融工具

在數字經濟加速滲透的今天,加密貨幣作為一種新型價值載體,正深刻改變著全球金融的運作邏輯。其中,穩定幣與非穩定幣構成了加密貨幣生態的兩大支柱,二者在設計邏輯、應用場景和市場表現上呈現出顯著差異。 穩定幣錨定法定貨幣 穩定幣是一類以法定貨幣、大宗商品或其他資產…

Constants

本節是《Solidity by Example》的中文翻譯與深入講解&#xff0c;專為零基礎或剛接觸區塊鏈開發的小白朋友打造。我們將通過“示例 解說 提示”的方式&#xff0c;帶你逐步理解每一段 Solidity 代碼的實際用途與背后的邏輯。 Solidity 是以太坊等智能合約平臺使用的主要編程語…

五鏡頭傾斜攝影相機的技術優勢與應用原理

傾斜攝影技術作為三維實景建模的核心手段&#xff0c;其硬件設計直接影響數據采集效率與模型質量。在眾多鏡頭配置方案中&#xff0c;五鏡頭結構&#xff08;下視前、后、左、右四個傾斜視角&#xff09;已成為行業主流選擇。這一設計并非偶然&#xff0c;而是基于嚴苛的技術需…

ThinkSound V2版 - 一鍵給無聲視頻配音,為AI視頻生成匹配音效 支持50系顯卡 一鍵整合包下載

ThinkSound 是阿里通義實驗室開源的首個音頻生成模型&#xff0c;它能夠讓AI像專業“音效師”一樣&#xff0c;根據視頻內容生成高度逼真、與視覺內容完美契合的音頻。 ThinkSound 可直接應用于影視后期制作&#xff0c;為AI生成的視頻自動匹配精準的環境噪音與爆炸聲效&#x…

如何從0開始構建自己的第一個AI應用?(Prompt工程、Agent自定義、Tuning)

一、前言 從0開始基于自定義Agent構建AI應用&#xff0c;涉及從創建智能Agent到使用、測試及優化提示詞等一系列步驟。前置&#xff1a;什么是LLM、Prompt、Mcp和Agent&#xff1f; 二、步驟一&#xff1a;規劃和設計AI應用 在創建AI應用之前&#xff0c;你需要明確應用的目標…

Java ThreadLocal詳解:從原理到實踐

Java ThreadLocal詳解&#xff1a;從原理到實踐&#xff08;圖解極簡示例&#xff09; 一、什么是ThreadLocal&#xff1f;——線程的"專屬儲物柜" ThreadLocal 是 Java 提供的線程本地存儲機制&#xff0c;通俗來說&#xff0c;它能為每個線程創建一個獨立的變量副本…