大家好鞋真,我是 V 哥崇堰,在鴻蒙HarmonyOS NEXT開發(fā)中,跨線程對象傳遞可以通過拷貝形式實現(xiàn)涩咖,確保兩個線程的對象內(nèi)容一致海诲,但各自指向線程的隔離內(nèi)存區(qū)間。以下是使用SharedArrayBuffer
實現(xiàn)跨線程共享內(nèi)存的完整案例代碼檩互,包括詳細解釋特幔,整理的學習筆記,分享給大家闸昨。關注威哥不迷路蚯斯,學習鴻蒙就很酷薄风。
案例代碼
1. 主線程代碼
@Component
export struct LockUsage {
taskNum: number = 10; // 任務數(shù),實際并行線程數(shù)依設備而定
baseDir: string = getContext().filesDir + '/TextDir'; // 文件寫入的應用沙箱路徑
sabInLock: SharedArrayBuffer = new SharedArrayBuffer(4); // 在主線程拍嵌,初始化子線程鎖標志位遭赂,所使用的共享內(nèi)存
sabForLine: SharedArrayBuffer = new SharedArrayBuffer(4); // 在主線程,初始化子線程偏移位横辆,所使用的共享內(nèi)存
@State result: string = "";
build() {
Row() {
Column() {
Button($r('app.string.not_use_lock'))
.width("80%").fontSize(30)
.fontWeight(FontWeight.Bold)
.margin({ top: 30 })
.onClick(async () => {
this.startWrite(false);
})
Button($r('app.string.use_lock'))
.width("80%")
.fontSize(30)
.fontWeight(FontWeight.Bold)
.margin({ top: 30 })
.onClick(async () => {
this.startWrite(true);
})
Text(this.result)
.width("80%")
.fontSize(30)
.fontWeight(FontWeight.Bold)
.fontColor(Color.Blue)
.margin({ top: 30 })
}
.width('100%')
}
.height('100%')
}
startWrite(useLock: boolean): void {
this.result = getContext().resourceManager.getStringSync($r('app.string.write_file_start'));
let whichLineToWrite: Int32Array = new Int32Array(this.sabForLine);
Atomics.store(whichLineToWrite, 0, 0);
let taskPoolGroup: taskpool.TaskGroup = new taskpool.TaskGroup();
for (let i: number = 0; i < this.taskNum; i++) {
taskPoolGroup.addTask(new taskpool.Task(createWriteTask, this.baseDir, i, this.sabInLock, this.sabForLine, useLock));
}
taskpool.execute(taskPoolGroup).then(() => {
this.result = getContext().resourceManager.getStringSync($r('app.string.write_file_success'));
}).catch(() => {
this.result = getContext().resourceManager.getStringSync($r('app.string.write_file_failed'));
})
}
}
2. 子線程代碼
@Concurrent
async function createWriteTask(baseDir: string, writeText: number, sabInLock: SharedArrayBuffer, sabForLine: SharedArrayBuffer, useLock: boolean): Promise<void> {
class Option {
offset: number = 0;
length: number = 0;
encoding: string = 'utf-8';
constructor(offset: number, length: number) {
this.offset = offset;
this.length = length;
}
}
let filePath: string | undefined = undefined;
filePath = baseDir + useLock ? "/useLock.txt" : "/unusedLock.txt";
if (!fs.accessSync(baseDir)) {
fs.mkdirSync(baseDir);
}
let nrl: NonReentrantLock | undefined = undefined;
if (useLock) {
nrl = new NonReentrantLock(sabInLock);
}
let whichLineToWrite: Int32Array = new Int32Array(sabForLine);
let str: string = writeText + '\n';
for (let i: number = 0; i < 100; i++) {
if (useLock && nrl !== undefined) {
nrl.lock();
}
let file: fs.File = fs.openSync(filePath, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
try {
fs.writeSync(file.fd, str, new Option(whichLineToWrite[0], str.length));
} catch (err) {
logger.error(`errorCode : ${err.code},errMessage : ${err.message}`);
}
fs.closeSync(file);
whichLineToWrite[0] += str.length;
if (useLock && nrl !== undefined) {
nrl.unlock();
}
}
}
詳細解釋
-
主線程初始化共享內(nèi)存:
-
sabInLock
和sabForLine
是兩個SharedArrayBuffer
對象撇他,分別用于子線程鎖標志位和偏移位。它們在主線程中被初始化狈蚤,并將被傳遞給子線程困肩,實現(xiàn)跨線程共享內(nèi)存。
-
-
子線程寫入文件:
- 子線程根據(jù)主線程傳入的
SharedArrayBuffer
初始化鎖和偏移量脆侮。 - 使用鎖確保線程安全锌畸,避免多個線程同時寫入文件時出現(xiàn)數(shù)據(jù)競爭。
- 通過
Atomics.store
和Atomics.load
操作共享內(nèi)存他嚷,實現(xiàn)線程間的同步蹋绽。
- 子線程根據(jù)主線程傳入的
-
線程間參數(shù)傳遞:
- 使用
taskpool.Task
創(chuàng)建子線程任務,并通過taskpool.execute
執(zhí)行筋蓖。 - 子線程任務通過
createWriteTask
函數(shù)實現(xiàn)卸耘,該函數(shù)接收主線程傳遞的參數(shù),包括文件路徑粘咖、寫入內(nèi)容蚣抗、鎖標志位和偏移位。
- 使用
-
線程安全寫入:
- 在寫入文件前瓮下,如果啟用鎖翰铡,則獲取鎖;寫入完成后釋放鎖讽坏,確保線程安全锭魔。
- 通過修改共享內(nèi)存中的偏移量,指定下次寫入的位置路呜,實現(xiàn)線程間的協(xié)作迷捧。
這個案例展示了如何在鴻蒙HarmonyOS NEXT開發(fā)中實現(xiàn)跨線程對象傳遞和共享內(nèi)存,確保線程安全和數(shù)據(jù)一致性胀葱。通過使用 SharedArrayBuffer
和線程間參數(shù)傳遞漠秋,可以實現(xiàn)高效的并發(fā)編程。關注威哥愛編程抵屿,一起向鴻蒙出發(fā)庆锦。