亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

我的修改方案就是直接將 fflush(NULL)這句去掉,這樣做會不會有什么風險?

我的修改方案就是直接將 fflush(NULL)這句去掉,這樣做會不會有什么風險?

C
翻過高山走不出你 2023-03-04 13:09:37
c程序中使用lua5.3.2庫來實現程序與lua腳本的調用,設計概要:1. 多線程調用lua的接口來實現對lua腳本的調用2. 多線程調用system實現其他任務這樣做概率性的會出現程序死鎖問題,下面是部分的堆棧信息:Thread 8 (Thread 0x7f7ae46f0700 (LWP 14392)):#0 0x00007f7b7ab03d1c in __lll_lock_wait_private () from /lib64/libc.so.6#1 0x00007f7b7aa7653d in _L_lock_121 () from /lib64/libc.so.6#2 0x00007f7b7aa74103 in __GI__IO_un_link () from /lib64/libc.so.6#3 0x00007f7b7aa6611d in fclose@@GLIBC_2.2.5 () from /lib64/libc.so.6#4 0x000000000046b2db in io_fclose ()#5 0x000000000045c1dc in luaD_precall ()#6 0x00000000004665a5 in luaV_execute ()#7 0x000000000045c59c in luaD_call ()Thread 4 (Thread 0x7f7ae26ec700 (LWP 14396)):#0 0x00007f7b7ab03d1c in __lll_lock_wait_private () from /lib64/libc.so.6#1 0x00007f7b7aa76640 in _L_lock_4452 () from /lib64/libc.so.6#2 0x00007f7b7aa75a08 in _IO_flush_all_lockp () from /lib64/libc.so.6#3 0x000000000046ba63 in io_popen ()Thread 181 (Thread 0x7f7b3af9d700 (LWP 14197)):#0 0x00007f7b7ab03d1c in __lll_lock_wait_private () from /lib64/libc.so.6#1 0x00007f7b7aa76728 in _L_lock_6097 () from /lib64/libc.so.6#2 0x00007f7b7aa7647f in __GI__IO_list_lock () from /lib64/libc.so.6#3 0x00007f7b7aabd087 in fork () from /lib64/libc.so.6#4 0x000000000044a302 in systemEx 經過定位,io_popen調用了l_popen#define l_popen(L,c,m) (fflush(NULL), popen(c,m))問題就在這句 fflush(NULL),這是這個操作導致了死鎖
查看完整描述

1 回答

?
長風秋雁

TA貢獻1757條經驗 獲得超7個贊

在C中調用Lua函數的API主要由以下幾個:
(1)void lua_call (lua_State *L, int nargs, int nresults);
函數調用,nargs表示參數的個數,nresults表示返回值的個數
首先將lua函數壓棧,然后將參數依次壓棧,最后調用函數即可
函數調用時,參數和函數都會pop出棧,調用返回后,結果會push進棧
nresults==LUA_MULTRET,所有的返回值都會push進棧
nresults!=LUA_MULTRET,返回值個數根據nresults來調整
Lua語句:
a = f("how", t.x, 14)
在C中的實現:
lua_getglobal(L, "f");        // 函數入棧
lua_pushstring(L, "how");     // 參數1入棧
lua_getglobal(L, "t");       // 表t入棧
lua_getfield(L, -1, "x");      // 參數2入棧
lua_remove(L, -2);        // 跳t出棧
lua_pushinteger(L, 14);     // 參數3入棧
lua_call(L, 3, 1);        // 調用函數,參數和函數都會出棧
lua_setglobal(L, "a");     // 給a賦值,棧頂出棧
上述代碼執行完畢后,堆棧狀態恢復原樣。
(2)int lua_pcall (lua_State *L, int nargs, int nresults, int msgh);
函數調用,在安全模式下,并且可以添加錯誤處理函數。
如果調用期間發生error,lua_pcall會捕獲之,然后push stack一個錯誤信息(會先將函數和參數pop出棧),并且返回一個error code(非0的一個值)。
發生error時,如果指定了錯誤處理函數,會在error message入棧前調用錯誤處理函數,具體由msgh參數來決定:
(1)msgh==0,不指定錯誤處理函數,入棧信息不變;
(2)msgh!=0,msgh表示錯誤處理函數的堆棧index,錯誤處理函數會以error message為參數,并將返回的新的error
message入棧。主要用來給error 
message添加  更多的debug信息,比如堆棧跟蹤,因為這些信息在pcall調用完之后是收集不到的。
函數返回代碼:
LUA_OK(0):調用成功
LUA_ERRRUN:runtime error
LUA_ERRMEM:內存分配錯誤,這種情況下不會調用錯誤處理函數
LUA_ERRERR:調用錯誤處理函數時出錯,當然,不會再進一步調用錯誤處理函數
LUA_ERRGCMM:調用metamethod.__gc時報錯,由gc引起,和函數本身沒關系
(3)int lua_pcallk (lua_State *L, int nargs, int nresults, int errfunc, int ctx, lua_CFunction k);
函數調用,在安全模式下,并且允許函數yield


查看完整回答
反對 回復 2023-03-06
  • 1 回答
  • 0 關注
  • 157 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號