2

ライブラリを使用してボタン付きのハードウェアデバイスにアクセスするLuaスクリプトを作成しています。ボタンの押下を処理するためのコールバック関数を登録します。コードは次のようになります。

globalvar = {}

function buttonCallback(buttonId)
    ...accessing globalvar
end

device.RegisterButtonCallback("buttonCallback")

while true do
end

これは機能します。

ここで、ボタンを押すだけでなく、1分間隔でglobalvarを更新したいと思います。とにかくネットワークリソースにアクセスする必要があるので、socket.select呼び出しを使用して1分間隔を取得する予定です。

#require "socket"

globalvar = {}

function buttonCallback(buttonId)
    ...access globalvar
end

device.RegisterButtonCallback("buttonCallback")

while true do
    socket.select(nil, nil, 60)  -- wait 60 seconds
    ...access network
    ...access globalvar
end

今、私はglobalvarの同時アクセスについて心配しています。ここで競合状態を防ぐにはどうすればよいですか?Luaのマルチスレッドに関するほとんどの情報源は、協調スケジューリングで継続を使用することを推奨していますが、私の場合、それをどのように適用できるかわかりません。

4

3 に答える 3

2

lua_StateLua は、特定のインスタンス内ではスレッドセーフではありません。別のスレッドがそのLuaインスタンスで何か他のことをしている間、あるスレッドからグローバル変数を変更することはできません。同じインスタンス上で 2 つの別々のスクリプトを実行することは絶対にありません。

スレッド セーフは、Lua の外部で行う必要があります。ボタンの押下を検出する C/C++ スレッドに実際に Lua コードを直接呼び出すことはできません。そのデータは、何らかのスレッドセーフなメカニズムを介してメイン スレッドに送信する必要があり、そこでLuaスクリプトを呼び出します。

于 2013-02-13T20:31:32.560 に答える
0

そこで、Lua の書籍やオンライン ドキュメントを詳しく調べて、デバイス ドライバーの作成者に連絡しました。回答がすでに示したように、ボタンのコールバックを安全に処理するには、予想以上に時間がかかります。

現在の私のアプローチは、デバイス ドライバーを自分で作成し、ソケットをデバイスと Lua スクリプト間の通信チャネルとして使用することです。

私の最初のアプローチは継続を使用することでした。これはマルチスレッドの Lua の「代替」として提唱されているためですが、Lua の本でプログラミングを読むと、ビジーな待機を防ぐために socket.select (!) を使用していることがわかりました。これにより、特にスクリプトでインターネット アクセス用のソケットも必要なため、ソケット ベースのアプローチが優れているという私の感覚が強まりました。

于 2013-03-11T21:04:58.003 に答える