C++20 多執行序的 semaphore

這篇來講一下 C++20 針對多執行序/併行(Concurrency)新增的另一個功能:semaphore(信號、C++ Reference)。

他的基本型別是 std::counting_semaphore,在內部擁有一個計數器來記錄總共可用的數量;這邊或許把他想像成總共有好幾張椅子,然後讓大家都要來坐的概念會比較好理解。

使用時基本上就是透過呼叫 acquire() 來向 counting_semaphore 要求一個位置、這時候它的內部記數器就會減 1、代表有一個位置被用掉了;而在用完之後,則是要透過呼叫 release() 這個函式來釋出位置、這時候內部計數器就會加 1。

閱讀更多»

Qt Visual Studio Tools 更新、提供 Qt MSBuild 獨立下載

「Qt Visual Studio Tools」(Visual Studio Marketplace)是 Qt 針對微軟的 Visual Studio 推出的延伸模組,在開發 Qt 的 C++ 專案的時候,他會幫忙完成很多建置階段的前置作業(moc、uic 等等),算是相當方便、好用的東西。

在 2021 年的時候,Heresy 也有寫過一篇《Qt Visual Studio Tools 的新版設定》來介紹當時新的 3.x 版和以前版本的不同。

而前幾天,Qt 則是發佈了新的 Qt Visual Studio Tools 3.2.0(官方部落格),它裡面有幾項比較大的改變:

  • 實驗性質支援 QML Language Server(預設是關閉的、官方說明
  • 支援 Visual Studio 2022 on ARM64

不過實際上,個人覺得比較有用的,反而是它終於提供 Qt MSBuild 的獨立下載了!

閱讀更多»

C++11 future 的 promise

前一篇基本上針對 C++11 <future>std::packaged_task<> 做了簡單的說明了,接下來,則來簡單紀錄一下 std::promise<>C++ Reference)吧。

首先,在 Heresy 來看,std::promise<> 基本上應該是 std::async()std::packaged_task<> 內部實作時使用的類別;它是設計成可以用來儲存一個值或是例外,然後之後可以透過對應的 std::future<> 來取得資料的類別。

在使用上,取得值的方法很單純,只有 get_future() 這個函式;透過這個函式可以取得 std::promise<> 對應的 std::future<> 物件,可以用來確認 std::promise<> 的狀態、並取得他的值。而如果 std::promise<> 物件是被設定成例外狀況的話,那在呼叫 std::future<>get() 的時候、就會丟出裡面儲存的例外。

閱讀更多»

C++11 的 packaged_task

Heresy 在 2016 年寫的《C++11 程式的平行化:async 與 future》這篇文章,基本上算是很簡單地介紹 C++11 新加入的 std::async()std::future<> 搭配使用的方法;而之前在《C++11 std::async 的運作分析》這篇文章,又大概分析了一下 std::async() 的運作模式。

而實際上,在 <future> 這個 header 裡面,除了 std::future<> 外,還有 std::promise<>std::packaged_task<> 這兩個類別可以使用。

這兩者基本上都是用來產生 std::future<> 用的,其中 std::promise<> 應該比較像是用在底層實作,而 std::packaged_task<> 則是用來打包既有的函式、轉換回傳值的型式的。

這邊就先來整理一下 std::packaged_task<> 這個東西(參考)了。

閱讀更多»

C++11 std::async 的運作分析

Heresy 在 2016 年的時候,有寫過一篇《C++11 程式的平行化:async 與 future》,介紹 C++11 新加入的 std::async()std::future<>

不過,Heresy 當時很直覺地認為、在透過 std::async() 執行工作的時候,如果指定 std::launch::async 的話,就會開一個新的執行序馬上去執行他;不過最近在重新研究 C++ 的平行化相關的各項功能的時候,才發現這部分其實是有些變數的。

首先,C++ Reference 上面的說明(網頁)是:

The function template std::async runs the function f asynchronously (potentially in a separate thread which might be a part of a thread pool) and returns a std::future that will eventually hold the result of that function call.

閱讀更多»

透過 Qt6 讀取麥克風、搭配 Whisper.cpp 進行語音辨識

這篇算是之前《使用 C++ 進行深度學習的語音辨識:Whisper.cpp》的延伸,來記錄一下要怎麼透過 Qt 6 來讀取麥克風的資料、並送給 Whisper.cpp 來進行語音辨識吧~

首先,這邊使用的 Qt 版本是 Qt 6.6.x(連結),「Qt Multimedia」這個模組(官網),在專案的設定必須要加入對應的模組設定。而由於這個模組在 Qt 6 重構過,所以在介面上會和之前 5.x 可能會有所不同,要使用的話最好先確認自己用的 Qt 是哪個版本。

閱讀更多»

使用 C++ 進行深度學習的語音辨識:Whisper.cpp

Whisper 是 OpenAI 在 2022 年推出來的通用語音辨識模型(GitHub)。他基本上支援多語言的偵測、也還有內建翻譯成英文的功能,基本上算是一個相當好的語音辨識框架。

而由於目前深度學習領域主流的開發環境還是 Python,所以不意外地,OpenAI 提供的開發環境也是以 Python 為主。

不過,目前 Georgi Gerganov 也有開發出 C API 的 whisper.cpp 專案(GitHub),它提供了可以在不需要額外的函示庫的狀況下使用的 whisper API,對於 C / C++ 的開發者來說,應該是相當地友善的~(注意,他只支援推論、不支援訓練)

這篇文章就先不管 Whisper 的原理和運作方式,單純就以 C++ 程式開發者為出發點,來記錄一下要怎麼透過 whisper.cpp 來撰寫一個語音辨識的程式吧!

閱讀更多»

Visual Studio 2022 17.9

Visual Studio 2022 在 2024 年的第一個大更新推出了~這次的版本是 17.9,官方的公告是《Visual Studio 2022 17.9 Now Available》,release note 的部分也可以參考官網的資訊;至於針對 C++ 的部分,則是《What’s New for C++ Developers in Visual Studio 2022 17.9》這篇。

至於有那些新功能或改進呢?在 Visual Studio IDE 中的「新增功能」頁面中,列出了下列的項目:

  • WinForms 設計工具改善
  • 摘要說明您的記憶體轉儲
  • VSConfig 現在支持延伸模組
  • 分析和追蹤「include」指示詞
  • 將 C++ 記憶體配置可視化
  • 快速切換索引標籤資料列樣式
  • 使用括號快速包圍您的程序代碼
  • 探索並啟用訂閱者權益
  • 適用於 .NET MAUI 的更佳屬性檢查
  • 快速識別事件處理程式流失
  • 在沒有視覺中斷的情況下進行偵錯
  • 更有效率地偵錯 .NET 8 程序代碼
  • 檢測「從收集暫停開始」選項
  • 讓 GitHub Copilot 產生 Git 認可訊息
  • 試用新的延伸模組管理員
  • 輕鬆驗證延伸模組擁有者
  • 搜尋所有一對一程式代碼搜尋中的任何文字

閱讀更多»

Kroki Docker 的原生 https 模式

之前 Heresy 曾經寫過一篇《在自架 GitLab 使用 Kroki 來繪圖》,介紹可以搭配 GitLab、在檔案、issue、wiki 裡面繪製 UML 等圖形的工具型伺服器了。

而在當時,他的 Docker 版並不支援 https、只支援 http,所以沒辦法直接搭配 Https 版的 GitLab 使用;後來 Heresy 是在對方的建議下使用 NGINX 來做反向代理、來讓他可以正常運作的(參考)。

實際上,後來他們也滿快地就就加入 Https 的支援了,不過 Docker 映像檔感覺是沒有立刻更新、再加上 Heresy 這邊可以正常運作、沒有迫切的需求,所以就先沒管了。

而前一陣子、Heresy 則是才又花了點時間、研究怎麼直接使用他的 https 模式,這邊就稍微紀錄一下。

閱讀更多»

C++ 多執行序開發中安全存取變數的 atomic

atomic(原子)在多執行序的程式開發中,算是一個很普遍的概念。它基本上就是將一些基本的存取操作定義成不可分割的操作(原子操作),然後搭配硬體設計、確保資料在多執行序的程式中可以更有效率地安全存取資料、保證不會出現 race condition 等等的問題。

而實際上,這部分大多還牽扯到 CPU 的架構,包含指令的執行順序(現在處理器可能是亂序執行)、快取等等,在 Heresy 來看算是相當底層的東西了。

其實像之前在介紹 OpenMP 的時候、其實有大概帶過 OpenMP 的 atomic 了,但是不知道為什麼,知其在介紹 std::thread 的時候,好像忘了這個基本的東西?這邊就來稍微補一下吧~不過老實說,太底層的東西 Heresy 也沒搞懂,所以這邊主要還是簡單的使用的部分了。

首先,什麼時候會需要用到 std:atomic<>參考)呢?下面是一個例子:

閱讀更多»