Dear Julia wizards: I understand that parallelism is still a work in progress, but I would like to know how to sketch the following code.
My code wants to maintain a shared (int) vector of what each CPU core is and/or has been working on. Before any core can alter this super-global “work in progress” queue, it needs to lock it. (Ideally, code would work both with shared memory threads and with full processes.) I very much like to define and type all my variables.
Here is an (incorrect) sketch of the task:
mutable struct WO; wo::Vector{Int}; n::Int, lock::SpinLock; end
function WO(n::Int) = workedon( fill(-1,n), n, **notlocked** ) ## constructor
w= WO(100) ## a new WO queue for 100 int tasks
function insert( w::WO, newtask::Int )
lock( w.lock )
for i=1:w.n ; (w[i]<0) && ( w[i]= newtask; break; ) ; end#for
unlock( w.lock )
end#function##
function taskof( w::WO, i::Int )
waitlockopen( w.lock )
w[i]
end#function##
any CPU core can call insert()
whenever it likes (without contention); and taskof()
won’t pull off a number while another process happens to be inserting. I am trying to give a minimal example—my real functions are much more involved.
I have many questions here, although better than detailed answers would be a template for how this should be done correctly. The questions are such as:
- Is
SpinLock
the right tool for multiple CPU coordination? - how do I initialize the lock in the constructor?
- is lock/unlock correct? how does another CPU test for state of lock?
- can one reasonably write code that works either with threads (sharing memory) or processes? the former works much better for small memory footprints; the latter for large memory footprints. (I know there are no
Sharedstruct
types.)
advice appreciated.
/iaw