I'm learning nim and porting some of my python code.
Here's a python program I'm trying to convert:
from threading import Thread, Lock
import time
lock=Lock()
threadlist=[]
data=0
threadAdata=0
threadBdata=0
def threadA():
global lock
global data
global threadAdata
threadAdata = 0
while threadAdata < 20 :
lock.acquire()
data+=1
threadAdata+=1
lock.release()
time.sleep(.5)
def threadB():
global lock
global data
global threadBdata
threadBdata = 0
while threadBdata < 20 :
lock.acquire()
data+=1
threadBdata+=1
lock.release()
time.sleep(0.25)
t=Thread(target=threadA,args=())
t.start()
threadlist.append(t)
t=Thread(target=threadB,args=())
t.start()
threadlist.append(t)
for t in threadlist :
t.join()
print("data:",data)
print("dataA:",threadAdata)
print("dataB:",threadBdata)
This is my attempt at conversion so far. Doesn't compile - see comments.
import
system, os, locks, tables, lists
var
lock : Lock
data = 0
threadAdata=0
threadBdata=0
threadslist : array[5,Thread] # this is wrong. it should NOT be fixed size. HAS to be runtime extensible. What is a better list/table?
proc A() {.thread.} =
threadAdata=0
while threadAdata < 20 :
acquire(L)
data = data + 1
threadAdata = threadAdata + 1
release(L)
sleep(500)
proc B() {.thread.} =
threadBdata=0
while threadBdata < 20 :
acquire(L)
data = data + 1
threadBdata = threadBdata + 1
release(L)
sleep(250)
# is this procedure even necessary?
proc AddThread(tp: proc (arg: TArg) {.thread, nimcall.}; param: TArg) : Thread =
# this is meant to create the thread and return a Thread
var
r : Thread
createThread(tp,r)
result = r
when isMainModule:
initLock(lock)
threadlist.append(AddThread(A))
threadlist.append(AddThread(B))
joinThreads(threadlist)
echo "data = " & data # should be 40
echo "dataA = " & threadAdata # should be 20
echo "dataB = " & threadBdata # should be 20
I'd like to keep the list of threads as I've got many threads to manage but the number of threads should be decided at runtime. This is just a simplified example to be clearer to understand.
If you want a working version of your port, here you go:
import
system, os, locks, tables, lists
var
L: Lock
data = 0
threadAdata = 0
threadBdata = 0
# make it a sequence if you want to have an arbitrary number
threadlist: seq[Thread[void]]
proc A() =
threadAdata = 0
while threadAdata < 20 :
acquire(L)
inc data
inc threadAdata
release(L)
sleep(500)
proc B() =
threadBdata = 0
while threadBdata < 20 :
acquire(L)
inc data
inc threadBdata
release(L)
sleep(250)
# make it a template to that we actually create the thread in the calling scope
template AddThread(tp: untyped): untyped =
var r : Thread[void]
createThread(r, tp)
r
when isMainModule:
initLock(L)
threadlist.add AddThread(A)
threadlist.add AddThread(B)
joinThreads(threadlist)
echo "data = ", data # should be 40
echo "dataA = ", threadAdata # should be 20
echo "dataB = ", threadBdata # should be 20