لينكس + ماك | ويندوز |
---|---|
Effil هي مكتبة متعددة الخيوط لـ Lua. يسمح بإنشاء سلاسل رسائل أصلية وتبادل آمن للبيانات. تم تصميم Effil لتوفير واجهة برمجة تطبيقات واضحة وبسيطة لمطوري Lua.
يدعم Effil إصدارات lua 5.1 و5.2 و5.3 وLuaJIT. يتطلب الامتثال للمترجم C++ 14. تم اختباره مع الإصدار 4.9+ من مجلس التعاون الخليجي، والإصدار 3.8 من clang، وVisual Studio 2015.
git clone --recursive https://github.com/effil/effil effil
cd effil && mkdir build && cd build
cmake .. && make install
luarocks install effil
كما تعلم، لا يوجد الكثير من لغات البرمجة النصية التي تدعم تعدد مؤشرات الترابط الحقيقي (Lua/Python/Ruby وغيرها لديها قفل مترجم عالمي يُعرف أيضًا باسم GIL). يحل Effil هذه المشكلة عن طريق تشغيل مثيلات Lua VM المستقلة في سلاسل رسائل أصلية منفصلة ويوفر أساسيات اتصال قوية لإنشاء سلاسل الرسائل ومشاركة البيانات.
توفر مكتبة Effil ثلاثة تجريدات رئيسية:
effil.thread
- يوفر واجهة برمجة التطبيقات (API) لإدارة سلاسل الرسائل.effil.table
- يوفر واجهة برمجة التطبيقات لإدارة الجداول. يمكن مشاركة الجداول بين المواضيع.effil.channel
- يوفر حاوية First-In-First-Out لتبادل البيانات التسلسلي.ومجموعة من الأدوات المساعدة للتعامل مع المواضيع والجداول أيضًا.
local effil = require ( " effil " )
function bark ( name )
print ( name .. " barks from another thread! " )
end
-- run funtion bark in separate thread with name "Spaky"
local thr = effil . thread ( bark )( " Sparky " )
-- wait for completion
thr : wait ()
الإخراج: Sparky barks from another thread!
local effil = require ( " effil " )
-- channel allow to push data in one thread and pop in other
local channel = effil . channel ()
-- writes some numbers to channel
local function producer ( channel )
for i = 1 , 5 do
print ( " push " .. i )
channel : push ( i )
end
channel : push ( nil )
end
-- read numbers from channels
local function consumer ( channel )
local i = channel : pop ()
while i do
print ( " pop " .. i )
i = channel : pop ()
end
end
-- run producer
local thr = effil . thread ( producer )( channel )
-- run consumer
consumer ( channel )
thr : wait ()
الإخراج:
push 1
push 2
pop 1
pop 2
push 3
push 4
push 5
pop 3
pop 4
pop 5
effil = require ( " effil " )
-- effil.table transfers data between threads
-- and behaves like regualr lua table
local storage = effil . table { string_field = " first value " }
storage . numeric_field = 100500
storage . function_field = function ( a , b ) return a + b end
storage . table_field = { fist = 1 , second = 2 }
function check_shared_table ( storage )
print ( storage . string_field )
print ( storage . numeric_field )
print ( storage . table_field . first )
print ( storage . table_field . second )
return storage . function_field ( 1 , 2 )
end
local thr = effil . thread ( check_shared_table )( storage )
local ret = thr : get ()
print ( " Thread result: " .. ret )
الإخراج:
first value
100500
1
2
Thread result: 3
يسمح Effil بنقل البيانات بين المواضيع (يشير مترجم Lua) باستخدام effil.channel
أو effil.table
أو مباشرة كمعلمات لـ effil.thread
.
nil
، boolean
، number
، string
lua_dump
. يتم التقاط القيم الأعلى وفقًا للقواعد.lua_iscfunction
صحيحًا) فقط عن طريق مؤشر باستخدام lua_tocfunction
(في lua_State الأصلية) ووظيفة lua_pushc (في lua_State الجديدة).lua_iscfunction
ترجع صحيحًا ولكن lua_tocfunction
ترجع nullptr. ولهذا السبب لا نجد طريقة لنقله بين lua_States.effil.table
بشكل متكرر. لذلك، يصبح أي جدول Lua effil.table
. قد يستغرق تسلسل الجدول الكثير من الوقت بالنسبة للجدول الكبير. وبالتالي، فمن الأفضل وضع البيانات مباشرة في effil.table
لتجنب تسلسل الجدول. دعونا نفكر في مثالين: -- Example #1
t = {}
for i = 1 , 100 do
t [ i ] = i
end
shared_table = effil . table ( t )
-- Example #2
t = effil . table ()
for i = 1 , 100 do
t [ i ] = i
end
في المثال رقم 1 قمنا بإنشاء جدول عادي وملئه وتحويله إلى effil.table
. في هذه الحالة، يحتاج Effil إلى مراجعة جميع حقول الجدول مرة أخرى. هناك طريقة أخرى في المثال رقم 2 حيث أنشأنا أولاً effil.table
وبعد ذلك قمنا بوضع البيانات مباشرة في effil.table
. الطريقة الثانية أسرع بكثير حاول اتباع هذا المبدأ.
جميع العمليات التي تستخدم مقاييس الوقت يمكن أن تكون محظورة أو غير محظورة وتستخدم واجهة برمجة التطبيقات التالية: (time, metric)
حيث يكون metric
هو الفاصل الزمني مثل 's'
(ثواني) time
هو عدد من الفواصل الزمنية.
مثال:
thread:get()
- انتظر بلا حدود حتى اكتمال الموضوع.thread:get(0)
- الحصول على غير محظور، ما عليك سوى التحقق من انتهاء الخيط والعودةthread:get(50, "ms")
- انتظر الحظر لمدة 50 مللي ثانية.قائمة الفترات الزمنية المتاحة:
ms
- ميلي ثانية.s
- ثانية (افتراضي)؛m
- دقيقة؛h
- ساعات.جميع عمليات الحظر (حتى في وضع عدم الحظر) هي نقاط انقطاع. يمكن مقاطعة الخيط المعلق في مثل هذه العملية عن طريق استدعاء طريقة الخيط: إلغاء ().
local effil = require " effil "
local worker = effil . thread ( function ()
effil . sleep ( 999 ) -- worker will hang for 999 seconds
end )()
worker : cancel ( 1 ) -- returns true, cause blocking operation was interrupted and thread was cancelled
العمل مع الوظائف، يقوم Effil بإجراء تسلسل لها وإلغاء تسلسلها باستخدام أساليب lua_dump
و lua_load
. يتم تخزين كافة القيم الأعلى للوظيفة باتباع نفس القواعد المعتادة. إذا كانت الوظيفة ذات قيمة أعلى من النوع غير المدعوم، فلا يمكن نقل هذه الوظيفة إلى Effil. سوف تحصل على خطأ في هذه الحالة.
العمل مع الوظيفة يمكن لـ Effil تخزين بيئة الوظيفة ( _ENV
) أيضًا. باعتبار البيئة جدولًا عاديًا، سيقوم Effil بتخزينها بنفس طريقة تخزين أي جدول آخر. لكن ليس من المنطقي تخزين _G
العمومي، لذلك هناك بعض الأمور المحددة:
_ENV ~= _G
). يمكن إيقاف effil.thread
مؤقتًا وإلغاؤه باستخدام الطرق المقابلة لكائن الخيط thread:cancel()
و thread:pause()
.
يمكن مقاطعة الخيط الذي تحاول مقاطعته في نقطتين للتنفيذ: صريحة وضمنية.
النقاط الصريحة هي effil.yield()
local thread = effil . thread ( function ()
while true do
effil . yield ()
end
-- will never reach this line
end )()
thread : cancel ()
النقاط الضمنية هي استدعاء ربط تصحيح الأخطاء lua الذي تم تعيينه باستخدام lua_sethook مع LUA_MASKCOUNT.
النقاط الضمنية اختيارية ويتم تمكينها فقط إذا كانت قيمة thread_runner.step > 0.
local thread_runner = effil . thread ( function ()
while true do
end
-- will never reach this line
end )
thread_runner . step = 10
thread = thread_runner ()
thread : cancel ()
بالإضافة إلى ذلك، يمكن إلغاء مؤشر الترابط (ولكن لا يتم إيقافه مؤقتًا) في أي عملية انتظار محظورة أو غير محظورة.
local channel = effil . channel ()
local thread = effil . thread ( function ()
channel : pop () -- thread hangs waiting infinitely
-- will never reach this line
end )()
thread : cancel ()
كيف يعمل الإلغاء؟
عندما تقوم بإلغاء مؤشر الترابط، فإنه يولد error
lua مع رسالة "Effil: thread is cancelled"
عندما يصل إلى أي نقطة انقطاع. هذا يعني أنه يمكنك اكتشاف هذا الخطأ باستخدام pcall
ولكن مؤشر الترابط سيولد خطأً جديدًا عند نقطة الانقطاع التالية.
إذا كنت تريد اكتشاف الخطأ الخاص بك ولكن تمرير خطأ الإلغاء، فيمكنك استخدام effil.pcall().
ستكون حالة الخيط الملغى مساوية للحالة cancelled
فقط إذا انتهت بخطأ في الإلغاء. هذا يعني أنه إذا اكتشفت خطأ في الإلغاء، فقد ينتهي مؤشر الترابط بالحالة completed
أو الحالة failed
إذا كان هناك خطأ آخر.
effil.thread
هي الطريقة لإنشاء سلسلة رسائل. يمكن إيقاف المواضيع وإيقافها مؤقتًا واستئنافها وإلغائها. يمكن أن تكون جميع العمليات باستخدام سلاسل الرسائل متزامنة (مع مهلة اختيارية) أو غير متزامنة. يعمل كل خيط بحالة Lua الخاصة به.
استخدم effil.table
و effil.channel
لنقل البيانات عبر المواضيع. انظر مثال على استخدام موضوع هنا.
runner = effil.thread(func)
يخلق عداء الموضوع. عداء يولد موضوع جديد لكل استدعاء.
الإدخال : وظيفة - وظيفة لوا
الإخراج : عداء - كائن عداء الموضوع لتكوين وتشغيل موضوع جديد
يسمح بتكوين وتشغيل موضوع جديد.
thread = runner(...)
قم بتشغيل الوظيفة الملتقطة باستخدام الوسائط المحددة في مؤشر ترابط منفصل وإرجاع مقبض مؤشر الترابط.
الإدخال : أي عدد من الوسائط التي تتطلبها الوظيفة الملتقطة.
الإخراج : كائن مقبض الخيط.
runner.path
هي قيمة Lua package.path
للحالة الجديدة. ترث القيمة الافتراضية الحالة الأصلية لنموذج package.path
.
runner.cpath
هي قيمة Lua package.cpath
للحالة الجديدة. ترث القيمة الافتراضية الحالة الأصلية لنموذج package.cpath
.
runner.step
عدد تعليمات lua بين نقاط الإلغاء (حيث يمكن إيقاف مؤشر الترابط أو إيقافه مؤقتًا). القيمة الافتراضية هي 200. إذا كانت هذه القيم 0، فإن مؤشر الترابط يستخدم نقاط الإلغاء الصريحة فقط.
يوفر مقبض مؤشر الترابط API للتفاعل مع مؤشر الترابط.
status, err, stacktrace = thread:status()
إرجاع حالة الموضوع.
الإخراج :
status
- تصف قيم السلسلة حالة الخيط. القيم المحتملة هي: "running", "paused", "cancelled", "completed" and "failed"
.err
- رسالة خطأ، إن وجدت. يتم تحديد هذه القيمة فقط إذا كانت حالة مؤشر الترابط == "failed"
.stacktrace
- تتبع المكدس للخيط الفاشل. يتم تحديد هذه القيمة فقط إذا كانت حالة مؤشر الترابط == "failed"
.... = thread:get(time, metric)
ينتظر إكمال مؤشر الترابط وإرجاع نتيجة الوظيفة أو لا شيء في حالة حدوث خطأ.
الإدخال : مهلة العملية من حيث مقاييس الوقت
الإخراج : نتائج استدعاء الوظيفة الملتقطة أو لا شيء في حالة الخطأ.
thread:wait(time, metric)
ينتظر اكتمال الخيط ويعيد حالة الخيط.
الإدخال : مهلة العملية من حيث مقاييس الوقت
الإخراج : إرجاع حالة الخيط. الإخراج هو نفس thread:status()
thread:cancel(time, metric)
يقاطع تنفيذ مؤشر الترابط. بمجرد استدعاء هذه الوظيفة، يتم تعيين علامة "الإلغاء" ويمكن إيقاف مؤشر الترابط في وقت ما في المستقبل (حتى بعد انتهاء استدعاء هذه الوظيفة). للتأكد من توقف مؤشر الترابط، قم باستدعاء هذه الوظيفة مع مهلة لا نهائية. إلغاء الخيط النهائي لن يفعل شيئًا وسيعود true
.
الإدخال : مهلة العملية من حيث مقاييس الوقت
الإخراج : إرجاع true
إذا تم إيقاف الموضوع أو false
.
thread:pause(time, metric)
يوقف الخيط مؤقتًا. بمجرد استدعاء هذه الوظيفة، يتم تعيين علامة "إيقاف مؤقت" ويمكن إيقاف مؤشر الترابط مؤقتًا في وقت ما في المستقبل (حتى بعد انتهاء استدعاء الوظيفة). للتأكد من إيقاف مؤشر الترابط مؤقتًا، قم باستدعاء هذه الوظيفة بمهلة لا نهائية.
الإدخال : مهلة العملية من حيث مقاييس الوقت
الإخراج : إرجاع true
إذا تم إيقاف مؤشر الترابط مؤقتًا أو false
. إذا اكتمل مؤشر الترابط، فستعود الوظيفة false
thread:resume()
يستأنف الموضوع المتوقف مؤقتا. تستأنف الوظيفة مؤشر الترابط فورًا إذا تم إيقافه مؤقتًا. هذه الوظيفة لا تفعل شيئًا للخيط المكتمل. لا تحتوي الوظيفة على معلمات الإدخال والإخراج.
id = effil.thread_id()
يعطي معرف فريد.
الإخراج : إرجاع id
سلسلة فريد لمؤشر الترابط الحالي .
effil.yield()
نقطة الإلغاء الصريحة. تقوم الوظيفة بالتحقق من علامات الإلغاء أو الإيقاف المؤقت لمؤشر الترابط الحالي وإذا كان ذلك مطلوبًا، فإنها تنفذ الإجراءات المقابلة (إلغاء مؤشر الترابط أو إيقافه مؤقتًا).
effil.sleep(time, metric)
تعليق الموضوع الحالي.
الإدخال : وسيطات مقاييس الوقت.
effil.hardware_threads()
إرجاع عدد المواضيع المتزامنة التي يدعمها التنفيذ. يقوم بشكل أساسي بإعادة توجيه القيمة من std::thread::hardware_concurrency.
الإخراج : عدد مؤشرات ترابط الأجهزة المتزامنة.
status, ... = effil.pcall(func, ...)
يعمل تمامًا بنفس الطريقة التي يعمل بها اتصال pcall القياسي باستثناء أنه لن يلتقط خطأ إلغاء سلسلة الرسائل الناتج عن استدعاء Thread:cancel().
مدخل:
الإخراج:
true
إذا لم يحدث أي خطأ، false
إذا لم يحدث ذلك effil.table
هي وسيلة لتبادل البيانات بين سلاسل effil. إنه يتصرف تقريبًا مثل جداول Lua القياسية. جميع العمليات مع الجدول المشترك آمنة لمؤشر الترابط. يقوم الجدول المشترك بتخزين الأنواع البدائية (الرقم والمنطق والسلسلة) والوظيفة والجدول وبيانات المستخدم الخفيفة وبيانات المستخدم المستندة إلى effil. لا يخزن الجدول المشترك سلاسل Lua (coroutines) أو بيانات المستخدم التعسفية. اطلع على أمثلة لاستخدام الجدول المشترك هنا
استخدام الجداول المشتركة مع الجداول العادية . إذا كنت ترغب في تخزين جدول عادي في جدول مشترك، فسوف يقوم effil ضمنيًا بتفريغ الجدول الأصلي في جدول مشترك جديد. تقوم الجداول المشتركة دائمًا بتخزين الجداول الفرعية كجداول مشتركة.
استخدم الجداول المشتركة مع الوظائف . إذا قمت بتخزين وظيفة في جدول مشترك، فإن effil يتخلص ضمنيًا من هذه الوظيفة ويحفظها كسلسلة (وهي قيم أعلى). سيتم التقاط جميع قيم الوظيفة وفقًا للقواعد التالية.
table = effil.table(tbl)
إنشاء جدول مشترك فارغ جديد.
الإدخال : tbl
- هو معلمة اختيارية ، يمكن أن يكون فقط جدول Lua العادي الذي سيتم نسخ الإدخالات فيه إلى الجدول المشترك.
الإخراج : مثيل جديد لجدول مشترك فارغ. يمكن أن يكون فارغًا أم لا، اعتمادًا على محتوى tbl
.
table[key] = value
قم بتعيين مفتاح جديد للجدول بقيمة محددة.
مدخل :
key
- أي قيمة من النوع المدعوم. راجع قائمة الأنواع المدعومةvalue
- أي قيمة من النوع المدعوم. راجع قائمة الأنواع المدعومةvalue = table[key]
احصل على قيمة من الجدول باستخدام المفتاح المحدد.
الإدخال : key
- أي قيمة من النوع المدعوم. راجع قائمة الأنواع المدعومة
الإخراج : value
- أي قيمة من النوع المدعوم. راجع قائمة الأنواع المدعومة
tbl = effil.setmetatable(tbl, mtbl)
يقوم بتعيين جدول تعريف جديد لجدول مشترك. على غرار setmetatable القياسية.
مدخل :
tbl
جدولًا مشتركًا تريد تعيين جدول تعريف له.mtbl
جدولًا عاديًا أو جدولًا مشتركًا والذي سيصبح قابلاً للتحويل. إذا كان جدولًا عاديًا، فسيقوم effil بإنشاء جدول مشترك جديد ونسخ جميع حقول mtbl
. قم بتعيين mtbl
يساوي nil
لحذف الجدول التعريفي من الجدول المشترك. الإخراج : فقط قم بإرجاع tbl
بقيمة قابلة للتحويل جديدة مشابهة لطريقة Lua setmetatable القياسية.
mtbl = effil.getmetatable(tbl)
إرجاع metatable الحالي. على غرار getmetatable القياسية
الإدخال : يجب أن يكون جدول tbl
مشتركًا.
الإخراج : إرجاع قابل للتحويل لجدول مشترك محدد. يحتوي الجدول الذي تم إرجاعه دائمًا على النوع effil.table
. الجدول التعريفي الافتراضي هو nil
.
tbl = effil.rawset(tbl, key, value)
قم بتعيين إدخال الجدول دون استدعاء metamethod __newindex
. على غرار الخام القياسي
مدخل :
tbl
هو جدول مشترك.key
- مفتاح الجدول لتجاوزه. يمكن أن يكون المفتاح من أي نوع مدعوم.value
- القيمة المراد ضبطها. يمكن أن تكون القيمة من أي نوع مدعوم. الإخراج : إرجاع نفس الجدول المشترك tbl
value = effil.rawget(tbl, key)
الحصول على قيمة الجدول دون استدعاء metamethod __index
. على غرار الخام القياسي
مدخل :
tbl
هو جدول مشترك.key
- مفتاح الجدول لتلقي قيمة محددة. يمكن أن يكون المفتاح من أي نوع مدعوم. الإخراج : إرجاع value
المطلوبة المخزنة تحت key
محدد
effil.G
هو جدول مشترك عالمي محدد مسبقًا. هذا الجدول موجود دائمًا في أي موضوع (أي ولاية لوا).
effil = require " effil "
function job ()
effil = require " effil "
effil . G . key = " value "
end
effil . thread ( job )(): wait ()
print ( effil . G . key ) -- will print "value"
result = effil.dump(obj)
يقوم بتحويل effil.table
إلى جدول Lua العادي.
tbl = effil . table ({})
effil . type ( tbl ) -- 'effil.table'
effil . type ( effil . dump ( tbl )) -- 'table'
effil.channel
هي وسيلة لتبادل البيانات بشكل تسلسلي بين سلاسل effil. يسمح بدفع الرسالة من موضوع واحد وإخراجها من موضوع آخر. رسالة القناة عبارة عن مجموعة من قيم الأنواع المدعومة. جميع العمليات مع القنوات آمنة. شاهد أمثلة لاستخدام القناة هنا
channel = effil.channel(capacity)
إنشاء قناة جديدة.
الإدخال : سعة اختيارية للقناة. إذا كانت capacity
تساوي 0
أو nil
فإن حجم القناة يكون غير محدود. القدرة الافتراضية هي 0
.
الإخراج : إرجاع مثيل جديد للقناة.
pushed = channel:push(...)
يدفع الرسالة إلى القناة.
الإدخال : أي عدد من قيم الأنواع المدعومة. تعتبر القيم المتعددة بمثابة رسالة قناة واحدة، لذا فإن الضغط على القناة مرة واحدة يؤدي إلى تقليل السعة بمقدار واحدة.
الإخراج : pushed
يساوي true
إذا كانت القيمة (-s) تناسب سعة القناة، false
بخلاف ذلك.
... = channel:pop(time, metric)
رسالة بوب من القناة. يزيل القيمة (-القيم) من القناة ويعيدها. إذا كانت القناة فارغة انتظر ظهور أي قيمة.
الإدخال : مهلة الانتظار من حيث مقاييس الوقت (يستخدم فقط إذا كانت القناة فارغة).
الإخراج : كمية متغيرة من القيم التي تم دفعها بواسطة استدعاء قناة واحدة: Push ().
size = channel:size()
احصل على الكمية الفعلية من الرسائل في القناة.
الإخراج : كمية الرسائل في القناة.
يوفر Effil أداة تجميع البيانات المهملة المخصصة لـ effil.table
و effil.channel
(والوظائف ذات القيم المرتفعة الملتقطة). يسمح بإدارة المراجع الدورية بشكل آمن للجداول والقنوات في سلاسل رسائل متعددة. ومع ذلك، فقد يتسبب ذلك في استخدام ذاكرة إضافية. يوفر effil.gc
مجموعة من طرق تكوين أداة تجميع البيانات المهملة effil. لكن عادةً لا تحتاج إلى تكوينه.
يقوم جامع البيانات المهملة بعمله عندما يقوم effil بإنشاء كائن مشترك جديد (جدول وقناة ووظائف ذات قيم أعلى تم التقاطها). يتحقق كل تكرار GC من عدد الكائنات. إذا أصبح مقدار الكائنات المخصصة أعلى، فستبدأ قيمة العتبة المحددة في تجميع البيانات المهملة. يتم حساب قيمة العتبة كـ previous_count * step
، حيث previous_count
- مقدار الكائنات في التكرار السابق ( 100 افتراضيًا) step
هي معامل رقمي محدد من قبل المستخدم ( 2.0 افتراضيًا).
على سبيل المثال: إذا كانت step
GC هي 2.0
وكمية الكائنات المخصصة هي 120
(المتبقية بعد تكرار GC السابق)، فسيبدأ GC في جمع البيانات المهملة عندما تكون كمية الكائنات المخصصة مساوية لـ 240
.
يتم تمثيل كل مؤشر ترابط كحالة Lua منفصلة مع أداة تجميع البيانات المهملة الخاصة بها. وبالتالي، سيتم حذف الكائنات في النهاية. كائنات Effil نفسها تتم إدارتها أيضًا بواسطة GC وتستخدم __gc
userdata metamethod كخطاف لإلغاء التسلسل. لفرض حذف الكائنات:
collectgarbage()
القياسي في كافة سلاسل الرسائل.effil.gc.collect()
في أي موضوع.effil.gc.collect()
فرض جمع البيانات المهملة، إلا أنه لا يضمن حذف كافة كائنات effil.
count = effil.gc.count()
إظهار عدد الجداول والقنوات المشتركة المخصصة.
الإخراج : إرجاع العدد الحالي من الكائنات المخصصة. الحد الأدنى للقيمة هو 1، effil.G
موجود دائمًا.
old_value = effil.gc.step(new_value)
الحصول على/تعيين مضاعف خطوة ذاكرة GC. الافتراضي هو 2.0
. يقوم GC بتشغيل عملية التجميع عندما تنمو كمية الكائنات المخصصة في أوقات step
.
الإدخال : new_value
هي قيمة اختيارية للخطوة المراد ضبطها. إذا كانت nil
، فستُرجع الدالة القيمة الحالية فقط.
الإخراج : old_value
هي القيمة الحالية (إذا كانت new_value == nil
) أو القيمة السابقة (إذا كانت new_value ~= nil
) للخطوة.
effil.gc.pause()
وقفة جي سي. لن يتم تنفيذ عملية جمع البيانات المهملة تلقائيًا. لا تحتوي الوظيفة على أي إدخال أو إخراج
effil.gc.resume()
استئناف جي سي. تمكين جمع البيانات المهملة تلقائيًا.
enabled = effil.gc.enabled()
الحصول على حالة GC.
الإخراج : يُرجع true
إذا تم تمكين التجميع التلقائي للبيانات المهملة أو false
بخلاف ذلك. بشكل افتراضي يعود true
.
size = effil.size(obj)
إرجاع عدد الإدخالات في كائن Effil.
الإدخال : obj
هو جدول أو قناة مشتركة.
الإخراج : عدد الإدخالات في الجدول المشترك أو عدد الرسائل في القناة
type = effil.type(obj)
المواضيع والقنوات والجداول هي بيانات المستخدم. وبالتالي، سيُرجع type()
userdata
لأي نوع. إذا كنت تريد اكتشاف النوع بشكل أكثر دقة، فاستخدم effil.type
. إنه يتصرف مثل type()
العادي، لكن يمكنه اكتشاف بيانات مستخدم محددة.
الإدخال : obj
هو كائن من أي نوع.
الإخراج : اسم السلسلة من النوع. إذا كان obj
هو كائن Effil، فإن الدالة ترجع سلسلة مثل effil.table
وفي حالات أخرى فإنها ترجع نتيجة الدالة lua_typename.
effil . type ( effil . thread ()) == " effil.thread "
effil . type ( effil . table ()) == " effil.table "
effil . type ( effil . channel ()) == " effil.channel "
effil . type ({}) == " table "
effil . type ( 1 ) == " number "