Updated lanes intergration
It is now at a point where I feel okay with documenting.
This commit is contained in:
parent
bf011646f7
commit
f072c2cfde
54
README.md
54
README.md
@ -1,5 +1,49 @@
|
|||||||
# multi Version: 1.6.0
|
# multi Version: 1.7.0 (Taking multi-tasking to the next level)
|
||||||
Updated from 1.5.0
|
Updated from 1.6.0 to 1.7.0
|
||||||
|
Modified: multi.intergration.lanesManager.lua
|
||||||
|
It is now in a stable and simple state Works with the latest lanes version! Tested with version 3.11 I cannot promise that everything will work with eariler versions. Future versions are good though.
|
||||||
|
Example Usage:
|
||||||
|
```lua
|
||||||
|
local GLOBAL,lthread=require("multi.intergration.lanesManager").init()
|
||||||
|
require("multi.alarm")
|
||||||
|
require("multi.threading")
|
||||||
|
multi:newAlarm(2):OnRing(function(self)
|
||||||
|
GLOBAL["NumOfCores"]=lthread.getCores()
|
||||||
|
end)
|
||||||
|
multi:newAlarm(7):OnRing(function(self)
|
||||||
|
GLOBAL["AnotherTest"]=true
|
||||||
|
end)
|
||||||
|
multi:newAlarm(13):OnRing(function(self)
|
||||||
|
GLOBAL["FinalTest"]=true
|
||||||
|
end)
|
||||||
|
multi:newSystemThread("test",function() -- spawns a thread in another lua process
|
||||||
|
require("multi.all") -- now you can do all of your coding with the multi library! You could even spawn more threads from here with the intergration. You would need to require the interaction again though
|
||||||
|
print("Waiting for variable: NumOfCores")
|
||||||
|
print("Got it: ",lthread.waitFor("NumOfCores"))
|
||||||
|
lthread.hold(function()
|
||||||
|
return GLOBAL["AnotherTest"] -- note this would hold the entire lthread. Spawn a coroutine thread using multi:newThread() or multi:newThreaded...
|
||||||
|
end)
|
||||||
|
print("Holding works!")
|
||||||
|
multi:newThread("tests",function()
|
||||||
|
thread.hold(function()
|
||||||
|
return GLOBAL["FinalTest"] -- note this will hold the entire lthread. As seen with the TLoop constantly going!
|
||||||
|
end)
|
||||||
|
print("Final test works!")
|
||||||
|
os.exit()
|
||||||
|
end)
|
||||||
|
local a=0
|
||||||
|
multi:newTLoop(function()
|
||||||
|
a=a+1
|
||||||
|
print(a)
|
||||||
|
end,.5)
|
||||||
|
multi:mainloop()
|
||||||
|
end)
|
||||||
|
multi:mainloop()
|
||||||
|
```
|
||||||
|
Onec I am happy with the intergration and feel it is ready I will document it better
|
||||||
|
|
||||||
|
|
||||||
|
Updated from 1.5.0 to 1.6.0
|
||||||
Changed: steps and loops
|
Changed: steps and loops
|
||||||
```lua
|
```lua
|
||||||
-- Was
|
-- Was
|
||||||
@ -22,11 +66,13 @@ Reasoning I wanted to keep objects consistant, but a lot of my older libraries u
|
|||||||
require("multi.all")
|
require("multi.all")
|
||||||
require("multi.compat.backwards[1,5,0]") -- allows for the use of features that were scrapped/changed in 1.6.0+
|
require("multi.compat.backwards[1,5,0]") -- allows for the use of features that were scrapped/changed in 1.6.0+
|
||||||
```
|
```
|
||||||
Updated from 1.4.1
|
Updated from 1.4.1 to 1.5.0
|
||||||
Added:
|
Added:
|
||||||
- An easy way to manage timeouts
|
- An easy way to manage timeouts
|
||||||
- Small bug fixes
|
- Small bug fixes
|
||||||
|
|
||||||
|
1.4.1 - First Public release of the library
|
||||||
|
|
||||||
IMPORTANT:
|
IMPORTANT:
|
||||||
Every update I make aims to make things simpler more efficent and just better, but a lot of old code, which can be really big, uses a lot of older features. I know the pain of having to rewrite everything. My promise to my library users is that I will always have backwards support for older features! New ways may exist that are quicker and eaiser, but the old features/methods will be supported.
|
Every update I make aims to make things simpler more efficent and just better, but a lot of old code, which can be really big, uses a lot of older features. I know the pain of having to rewrite everything. My promise to my library users is that I will always have backwards support for older features! New ways may exist that are quicker and eaiser, but the old features/methods will be supported.
|
||||||
|
|
||||||
@ -35,7 +81,7 @@ Example at end of the readme
|
|||||||
My multitasking library for lua</br>
|
My multitasking library for lua</br>
|
||||||
To install copy the multi folder into your enviroment and you are good to go</br>
|
To install copy the multi folder into your enviroment and you are good to go</br>
|
||||||
|
|
||||||
It is a pure lua binding if you ingore the intergrations (WIP)</br>
|
It is a pure lua binding if you ingore the intergrations (Stable!)</br>
|
||||||
|
|
||||||
If you find any bugs or have any issues please let me know :)
|
If you find any bugs or have any issues please let me know :)
|
||||||
|
|
||||||
|
|||||||
37
lanesintergratetest.lua
Normal file
37
lanesintergratetest.lua
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
package.path="?/init.lua;?.lua;"..package.path
|
||||||
|
local GLOBAL,lthread=require("multi.intergration.lanesManager").init()
|
||||||
|
require("multi.alarm")
|
||||||
|
require("multi.threading")
|
||||||
|
for i,v in pairs(lanes.ABOUT) do print(i,v) end
|
||||||
|
multi:newAlarm(2):OnRing(function(self)
|
||||||
|
GLOBAL["NumOfCores"]=lthread.getCores()
|
||||||
|
end)
|
||||||
|
multi:newAlarm(7):OnRing(function(self)
|
||||||
|
GLOBAL["AnotherTest"]=true
|
||||||
|
end)
|
||||||
|
multi:newAlarm(13):OnRing(function(self)
|
||||||
|
GLOBAL["FinalTest"]=true
|
||||||
|
end)
|
||||||
|
multi:newSystemThread("test",function() -- spawns a thread in another lua process
|
||||||
|
require("multi.all") -- now you can do all of your coding with the multi library! You could even spawn more threads from here with the intergration. You would need to require the interaction again though
|
||||||
|
print("Waiting for variable: NumOfCores")
|
||||||
|
print("Got it: ",lthread.waitFor("NumOfCores"))
|
||||||
|
lthread.hold(function()
|
||||||
|
return GLOBAL["AnotherTest"] -- note this would hold the entire lthread. Spawn a coroutine thread using multi:newThread() or multi:newThreaded...
|
||||||
|
end)
|
||||||
|
print("Holding works!")
|
||||||
|
multi:newThread("tests",function()
|
||||||
|
thread.hold(function()
|
||||||
|
return GLOBAL["FinalTest"] -- note this will hold the entire lthread. As seen with the TLoop constantly going!
|
||||||
|
end)
|
||||||
|
print("Final test works!")
|
||||||
|
os.exit()
|
||||||
|
end)
|
||||||
|
local a=0
|
||||||
|
multi:newTLoop(function()
|
||||||
|
a=a+1
|
||||||
|
print(a)
|
||||||
|
end,.5)
|
||||||
|
multi:mainloop()
|
||||||
|
end)
|
||||||
|
multi:mainloop()
|
||||||
@ -22,7 +22,7 @@ function print(...)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
multi = {}
|
multi = {}
|
||||||
multi.Version={1,6,0}
|
multi.Version={1,6,1}
|
||||||
multi.stage='stable'
|
multi.stage='stable'
|
||||||
multi.__index = multi
|
multi.__index = multi
|
||||||
multi.Mainloop={}
|
multi.Mainloop={}
|
||||||
|
|||||||
@ -8,7 +8,7 @@ end
|
|||||||
-- Step 1 get lanes
|
-- Step 1 get lanes
|
||||||
lanes=require("lanes").configure()
|
lanes=require("lanes").configure()
|
||||||
package.path="lua/?/init.lua;lua/?.lua;"..package.path
|
package.path="lua/?/init.lua;lua/?.lua;"..package.path
|
||||||
require("multi.all") -- get it all and have it on all lanes
|
require("multi.updater") -- get it all and have it on all lanes
|
||||||
local multi=multi
|
local multi=multi
|
||||||
-- Step 2 set up the linda objects
|
-- Step 2 set up the linda objects
|
||||||
local __GlobalLinda = lanes.linda() -- handles global stuff
|
local __GlobalLinda = lanes.linda() -- handles global stuff
|
||||||
@ -31,8 +31,21 @@ end
|
|||||||
function THREAD.get(name)
|
function THREAD.get(name)
|
||||||
__GlobalLinda:get(name)
|
__GlobalLinda:get(name)
|
||||||
end
|
end
|
||||||
|
local function randomString(n)
|
||||||
|
local str = ''
|
||||||
|
local strings = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','1','2','3','4','5','6','7','8','9','0','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'}
|
||||||
|
for i=1,n do
|
||||||
|
str = str..''..strings[math.random(1,#strings)]
|
||||||
|
end
|
||||||
|
return str
|
||||||
|
end
|
||||||
function THREAD.waitFor(name)
|
function THREAD.waitFor(name)
|
||||||
--
|
local function wait()
|
||||||
|
math.randomseed(os.time())
|
||||||
|
__SleepingLinda:receive(.001,randomString(12))
|
||||||
|
end
|
||||||
|
repeat wait() until __GlobalLinda:get(name)
|
||||||
|
return __GlobalLinda:get(name)
|
||||||
end
|
end
|
||||||
function THREAD.testFor(name,val,sym)
|
function THREAD.testFor(name,val,sym)
|
||||||
--
|
--
|
||||||
@ -45,63 +58,24 @@ if os.getOS()=="windows" then
|
|||||||
else
|
else
|
||||||
THREAD.__CORES=tonumber(io.popen("nproc --all"):read("*n"))
|
THREAD.__CORES=tonumber(io.popen("nproc --all"):read("*n"))
|
||||||
end
|
end
|
||||||
-- Step 4 change the coroutine threading methods to work the same, but with lanes TODO when the lanes scheduler is ready!
|
|
||||||
function THREAD.skip(n)
|
|
||||||
-- Do Nothing
|
|
||||||
end
|
|
||||||
function THREAD.kill() -- trigger the lane destruction
|
function THREAD.kill() -- trigger the lane destruction
|
||||||
-- coroutine.yield({"_kill_",":)"})
|
-- coroutine.yield({"_kill_",":)"})
|
||||||
end
|
end
|
||||||
--[[ Step 5 We need to get sleeping working so we need a lane to handle timing... We want idle wait not busy wait
|
--[[ Step 4 We need to get sleeping working to handle timing... We want idle wait, not busy wait
|
||||||
Idle wait keeps the CPU running better where busy wait wastes CPU cycles... Lanes does not have a sleep method
|
Idle wait keeps the CPU running better where busy wait wastes CPU cycles... Lanes does not have a sleep method
|
||||||
however, a linda recieve will in fact be a idle wait! So when wait is called we can pack the cmd up and send it to
|
however, a linda recieve will in fact be a idle wait! So we use that and wrap it in a nice package]]
|
||||||
the sleeping thread manager to send the variable for the other thread to consume, sending only after a certain time has passed!
|
|
||||||
]]
|
|
||||||
local function randomString(n)
|
|
||||||
local str = ''
|
|
||||||
local strings = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','1','2','3','4','5','6','7','8','9','0','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'}
|
|
||||||
for i=1,n do
|
|
||||||
str = str..''..strings[math.random(1,#strings)]
|
|
||||||
end
|
|
||||||
return str
|
|
||||||
end
|
|
||||||
function THREAD.sleep(n)
|
function THREAD.sleep(n)
|
||||||
math.randomseed(os.time())
|
math.randomseed(os.time())
|
||||||
local randKey=randomString(12) -- generate a random string a-Z and 0-9
|
__SleepingLinda:receive(n,randomString(12))
|
||||||
__SleepingLinda:send("tired","SLEEP|"..randKey.."|"..tostring(n)) -- send the data that needs to be managed
|
|
||||||
local dat=__SleepingLinda:receive(randKey)
|
|
||||||
return dat
|
|
||||||
end
|
end
|
||||||
function THREAD.hold(n)
|
function THREAD.hold(n)
|
||||||
while not(n()) do
|
local function wait()
|
||||||
-- holding
|
math.randomseed(os.time())
|
||||||
|
__SleepingLinda:receive(.001,randomString(12))
|
||||||
end
|
end
|
||||||
|
repeat wait() until n()
|
||||||
end
|
end
|
||||||
-- start the time manager lane
|
-- Step 5 Basic Threads!
|
||||||
--~ lanes.gen("*", function()
|
|
||||||
--~ local timers={}
|
|
||||||
--~ while true do -- forever loop!
|
|
||||||
--~ local data=__SleepingLinda:receive(.001,"tired") -- timeout after .001 seconds and handle the other stuff
|
|
||||||
--~ if data then -- the .001 is an entarnal timer that keeps this thread from using too much CPU as well!
|
|
||||||
--~ print(data)
|
|
||||||
--~ local cmd,key,sec=data:match("(%S-)|(%S-)|(.+)")
|
|
||||||
--~ if cmd=="SLEEP" then
|
|
||||||
--~ print("GOT!")
|
|
||||||
--~ timers[#timers+1]={os.clock()+tonumber(sec),key}
|
|
||||||
--~ --__SleepingLinda:set()
|
|
||||||
--~ elseif cmd=="audit" then
|
|
||||||
--~ --
|
|
||||||
--~ end
|
|
||||||
--~ end
|
|
||||||
--~ for i=1,#timers do
|
|
||||||
--~ if os.clock()>=timers[i][1] then
|
|
||||||
--~ __SleepingLinda:send(timers[i][2],true)
|
|
||||||
--~ table.remove(timers,i)
|
|
||||||
--~ end
|
|
||||||
--~ end
|
|
||||||
--~ end
|
|
||||||
--~ end)() -- The global timer is now activated, and it works great!
|
|
||||||
-- Step 6 Basic Threads!
|
|
||||||
function multi:newSystemThread(name,func)
|
function multi:newSystemThread(name,func)
|
||||||
local c={}
|
local c={}
|
||||||
local __self=c
|
local __self=c
|
||||||
@ -123,5 +97,9 @@ function multi:newSystemThread(name,func)
|
|||||||
end)
|
end)
|
||||||
return c
|
return c
|
||||||
end
|
end
|
||||||
_G["GLOBAL"]=GLOBAL
|
print("Intergrated Lanes!")
|
||||||
_G["__GlobalLinda"]=__GlobalLinda
|
multi.intergration={} -- for module creators
|
||||||
|
multi.intergration.lanes={} -- for module creators
|
||||||
|
multi.intergration.lanes.GLOBAL=GLOBAL -- for module creators
|
||||||
|
multi.intergration.lanes.THREAD=THREAD -- for module creators
|
||||||
|
return {init=function() return GLOBAL,THREAD end}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user