這個故事是發生在 Qt 4.x 身上.在這個版本中,要 parsing JSON,最簡單的方式就是用 QScriptEngine 去呼叫 JavaScript 來 parsing,再用 QScriptValue 得到結果即可(註:在 Qt 5.0 之後已有現成 API 可以使用 https://qt-project.org/doc/qt-5.0/qtcore/json.html).

但 QtScript 中的許多函式並不是 thread-safe,如很常使用到的 QScriptEngine::evaluate(),QScriptValue::call() 如果你multi-thead 去執行,將會得到不可預期的結果.

看一下QScriptValue 的 source code,可以發現到它會出問題的點可能跟使用 d->engine->currentFrame 有關.(當然,可能還有很多地方都不是 thread-safe,必竟原本就不是要設計成 thread-safe)

1558 QScriptValue QScriptValue::call(const QScriptValue &thisObject,
1559 const QScriptValueList &args)
1560 {
1561 Q_D(const QScriptValue);
1562 if (!d || !d->isObject())
1563 return QScriptValue();
1564 QScript::APIShim shim(d->engine);
1565 JSC::JSValue callee = d->jscValue;
1566 JSC::CallData callData;
1567 JSC::CallType callType = callee.getCallData(callData);
1568 if (callType == JSC::CallTypeNone)
1569 return QScriptValue();
1570
1571 if (QScriptValuePrivate::getEngine(thisObject)
1572 && (QScriptValuePrivate::getEngine(thisObject) != d->engine)) {
1573 qWarning("QScriptValue::call() failed: "
1574 "cannot call function with thisObject created in "
1575 "a different engine");
1576 return QScriptValue();
1577 }
1578
1579 JSC::ExecState *exec = d->engine->currentFrame;
1580
1581 JSC::JSValue jscThisObject = d->engine->scriptValueToJSCValue(thisObject);
1582 if (!jscThisObject || !jscThisObject.isObject())
1583 jscThisObject = d->engine->globalObject();

 

 

創作者介紹
創作者 diro 的頭像
diro

Diro - 探索生活中的美好事物

diro 發表在 痞客邦 留言(0) 人氣()