fix: add thread safety for pinyin dictionary initialization#556
fix: add thread safety for pinyin dictionary initialization#556deepin-bot[bot] merged 1 commit intolinuxdeepin:masterfrom
Conversation
[Current thread is 1 (Thread 0x7f3afe04f6c0 (LWP 37684))]
(gdb) thread 3 |
91766f1 to
73cb085
Compare
Add mutex protection to prevent race condition in multi-threaded access to the static pinyin dictionary. The `InitDict()` function was not thread-safe when called concurrently from multiple threads, which could lead to double initialization or data corruption. 1. Add `QMutex` and `QMutexLocker` includes 2. Declare static `dictMutex` to protect the dictionary 3. Lock mutex at the beginning of `InitDict()` to ensure exclusive access 4. Prevent potential crash when multiple threads simultaneously trigger dictionary loading Influence: 1. Test concurrent pinyin conversion from multiple threads 2. Verify no crash occurs during high-frequency multi-threaded access 3. Test dictionary initialization under thread contention 4. Verify performance impact of mutex locking in single-threaded scenarios 5. Test edge cases where InitDict is called simultaneously from different threads fix: 添加拼音字典初始化的线程安全保护 添加互斥锁保护以防止多线程访问静态拼音字典时的竞态条件。`InitDict()` 函 数在被多线程并发调用时不是线程安全的,可能导致重复初始化或数据损坏。 1. 添加 `QMutex` 和 `QMutexLocker` 头文件包含 2. 声明静态 `dictMutex` 用于保护字典 3. 在 `InitDict()` 开头加锁以确保独占访问 4. 防止多线程同时触发字典加载时可能导致的崩溃 Influence: 1. 测试多线程并发进行拼音转换的场景 2. 验证高频多线程访问时无崩溃发生 3. 测试线程竞争条件下的字典初始化 4. 验证单线程场景下互斥锁锁定的性能影响 5. 测试不同线程同时调用 InitDict 的边界情况
deepin pr auto review这段代码的修改主要涉及到了版权年份更新、头文件包含顺序调整、以及字典初始化逻辑的线程安全改进。下面是对这段代码的详细审查和改进建议: 1. 语法逻辑审查优点:
建议:
2. 代码质量审查优点:
建议:
3. 代码性能审查优点:
建议:
4. 代码安全审查优点:
建议:
5. 其他改进建议
改进后的代码示例// SPDX-FileCopyrightText: 2019 - 2026 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: LGPL-3.0-or-later
#include "dpinyin.h"
#include <QFile>
#include <QMap>
#include <QSet>
#include <QTextStream>
#include <QDebug>
#include <mutex>
DCORE_BEGIN_NAMESPACE
constexpr char kDictFile[] = ":/dpinyin/resources/dpinyin.dict";
static QHash<uint, QString> dict = {};
static std::once_flag dictInitFlag;
static void initDictImpl()
{
dict.reserve(25333); // 建议根据实际字典大小调整
QFile file(kDictFile);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
qWarning() << "Failed to open dictionary file:" << kDictFile;
return;
}
QTextStream in(&file);
while (!in.atEnd()) {
QString line = in.readLine();
QStringList parts = line.split(' ');
if (parts.size() != 2) {
qWarning() << "Invalid dictionary line:" << line;
continue;
}
bool ok;
uint key = parts[0].toUInt(&ok, 16);
if (!ok) {
qWarning() << "Invalid hex key in dictionary:" << parts[0];
continue;
}
dict[key] = parts[1];
}
}
static void InitDict()
{
std::call_once(dictInitFlag, initDictImpl);
}
static void initToneTable(QMap<QChar, QString> &toneTable)
{
if (!toneTable.isEmpty()) {
return;
}
toneTable.insert('ā', "a1");
toneTable.insert('á', "a2");
toneTable.insert('ǎ', "a3");
toneTable.insert('à', "a4");
// 其他拼音字符...
}
static QString toned(const QString &str, ToneStyle ts)
{
static QMap<QChar, QString> toneTable;
initToneTable(toneTable);
QString newStr = str;
QString toneNum = "";
// First pass: find tone number and remove tone marks
for (QChar c : str) {
if (toneTable.contains(c)) {
newStr.replace(c, toneTable[c][0]);
toneNum += toneTable[c][1];
if (ts == TS_ToneNone) {
newStr = str; // 重置为原始字符串
break;
}
}
}
// For TS_ToneNum, append tone number at the end
if (ts == TS_ToneNum && !toneNum.isEmpty()) {
newStr += toneNum;
}
return newStr;
}总结这段代码的改进方向主要集中在线程安全、错误处理和代码可维护性上。通过使用 |
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: 18202781743, caixr23 The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
|
/forcemerge |
|
This pr force merged! (status: blocked) |
Add mutex protection to prevent race condition in multi-threaded access to the static pinyin dictionary. The
InitDict()function was not thread-safe when called concurrently from multiple threads, which could lead to double initialization or data corruption.QMutexandQMutexLockerincludesdictMutexto protect the dictionaryInitDict()to ensure exclusive accessInfluence:
fix: 添加拼音字典初始化的线程安全保护
添加互斥锁保护以防止多线程访问静态拼音字典时的竞态条件。
InitDict()函数在被多线程并发调用时不是线程安全的,可能导致重复初始化或数据损坏。
QMutex和QMutexLocker头文件包含dictMutex用于保护字典InitDict()开头加锁以确保独占访问Influence: