How to pass parameters to a thread?

BlitzMax Forums/BlitzMax Programming/How to pass parameters to a thread?

taumel(Posted 2010) [#1]
I just had my first try at threading and was wondering how to pass multiple parameters to a thread. Couldn't pass them directly nor by type, just a single string. Do you have to build a string containing the different parameters and parse this one in the thread on your own or how does it work?

Thanks


BlitzSupport(Posted 2010) [#2]
You should be able to pass your own type by doing something like this (from memory):

Type MyType
	Field x:Int
	Field y:Int
End Type

Function MyThread:Object (obj:Object)

	Local test:MyType = MyType (obj)
	
	Print test.x
	Print test.y

	... etc...




taumel(Posted 2010) [#3]
And i create the thread via

Local dumType:MyType = New MyType
dumThread:TThread=CreateThread(MyThread,dumType:MyType)

right?

It then compiles but crashes on me.


Thareh(Posted 2010) [#4]
What's "MyThread" you use as a first parameter?
I think the code above should work without problems ^^

Last edited 2010


taumel(Posted 2010) [#5]
I think i have an issue with arranging it properly in the loop...

Btw is passing the object type for threads done by call by reference or call by value?

Last edited 2010


Thareh(Posted 2010) [#6]
Here's how I've done my multithreading code :)

		If AcceptFunc = Null Then Return
		
		Accept = SocketAccept( Socket )
		If Accept
			Local Thread:TThread = CreateThread( NewConnection, TWebInterfaceEntrance.Create( Accept, Self ) )
			ListAddLast( ThreadList, Thread )
		EndIf
		
		If CountList( ThreadList ) > 0
			For Local Thread:TThread = EachIn ThreadList
				If ThreadRunning( Thread ) = False
					ListRemove( ThreadList, Thread )
					DetachThread( Thread )
				EndIf
			Next
		EndIf


And in the NewConnection function, I just call this:
Local Session:TSession = TSession.Create( TWebInterfaceEntrance( Obj ).Socket )


Last edited 2010


Czar Flavius(Posted 2010) [#7]
Not ListIsEmpty is faster than testing CountList > 0

Last edited 2010


Thareh(Posted 2010) [#8]
Oh okey, Thank you :)
I love small optimizations :D


Czar Flavius(Posted 2010) [#9]
Actually now that I think about it, the check itself is unnecessary! :D
If the list is empty, the For EachIn loop will just skip itself normally. You don't need to check first.

There is another optimization to be had, but it's not really worth it unless your list is going to contain hundreds of items.

Last edited 2010


taumel(Posted 2010) [#10]
Do you need to detach threads on your own?


Thareh(Posted 2010) [#11]
Yeah, You're right :P
But it's an old habbit from when I started using BlitzMax and my apps crashed if I tried to do an EachIn on an empty list :P

What's the other optimization? :D


Czar Flavius(Posted 2010) [#12]
I think EachIn on a Null list would crash, but not an empty one.

ListRemove is slow as it traverses the list one-by-one until it finds your object., although it doesn't really matter unless your list contains hundreds of items.

When you add something to a list, it returns a TLink which acts like a bookmark to that object in the list. If you store this TLink inside the Type, then you can tell the TLink to remove itself and the object will be removed from the list quickly.


BlitzSupport(Posted 2010) [#13]

Type MyType
	Field x:Int
	Field y:Int
End Type

Function MyThread:Object (obj:Object)

	Local test:MyType = MyType (obj)

	Print test.x
	Delay 1000	
	
	Print test.y
	Delay 1000

End Function








Local mt:MyType = New MyType

mt.x = 1
mt.y = 2

Local dumThread:TThread = CreateThread (MyThread, mt)

WaitThread dumThread ' Wait for thread to exit...

End



This works for me. You don't generally need to detach, as once the thread exits, the garbage collector will deal with that.


Richard Betson(Posted 2010) [#14]
@James
I also new to coding threads. Very interesting.


taumel(Posted 2010) [#15]
@BlitzSupport

Thanks. I guess i mixed something up on my side.

Okay, if i got things right, i can't call functions like WritePixel in multiple threads without taking care of it via Mutex for instance. How does it work with functions which just contain some logic and write to locals, those can be called multiple times without locking it , right? And, is the data passed to a thread called by reference or value?

Last edited 2010


BlitzSupport(Posted 2010) [#16]
I'm no threading expert, but...


How does it work with functions which just contain some logic and write to locals



That should be fine, as long as your function doesn't access global values (unless they're locked/unlocked via mutexes), or call other functions which access globals.

Not sure about WritePixel between multiple threads, assuming you mean they're all writing strictly to their own section of the same Pixmap (?). That might be OK, depending on how you synchronise things (eg. if calling LockImage to get a Pixmap).


is the data passed to a thread called by reference or value?



I would have said by value at first, looking at the source, but I believe objects are passed by reference in general.

This seems to suggest so, the thread modifying the values and the main thread showing those modified values after the thread quits:

Type MyType
	Field x:Int
	Field y:Int
End Type

Function MyThread:Object (obj:Object)

	Local test:MyType = MyType (obj)

	test.x = 3
	test.y = 4

End Function








Local mt:MyType = New MyType

mt.x = 1
mt.y = 2

Local dumThread:TThread = CreateThread (MyThread, mt)

WaitThread dumThread ' Wait for thread to exit...

Print mt.x
Print mt.y

End


An interesting point to note is that with WaitThread commented out you will probably get the original values, depending on which out of the main thread and MyThread gets there first on your particular setup!

(Quick repeat-run test shows mostly 1/2 but one run in every 5 or 10 gives 3/4 here.)


BlitzSupport(Posted 2010) [#17]
In my limited experience, BTW, I would only use threads for:

1) Experimenting -- they're cool to play with;
2) Background network/disk access while main program runs;
3) Loading screen-type displays, ie. main thread shows animated screen while child thread loads images/data in the background.


taumel(Posted 2010) [#18]
Okay, thanks! Let's see where this will lead me when i find some more time.

Last edited 2010


ima747(Posted 2010) [#19]
I punched up a little tutorial on threading a while ago, might be of some use

http://www.blitzbasic.com/Community/posts.php?topic=91458


taumel(Posted 2010) [#20]
Thanks, i'll have a look at it.

Performance wise, is it best to access arrays and variables, if they change a lot, via globals or passing them via fields to the thread?

After a few Mallocs (sometimes my fault, sometimes i thought it wasn't mine), here is my first threading tryout: http://blitzmax.com/Community/posts.php?topic=91294#1053106

There must be going something wrong because i would have expected more than a 60% increase with the threaded version.

Last edited 2010


taumel(Posted 2010) [#21]
And how far,memory wise, can locals be adressed in BlitzMax?

Last edited 2010