my goal is to understand what happens when t := tmthread.create(i); is called
why the tmthread,create doesn't need to be passed 'ch'
my understanding : tmthread.execute is in the tmthread class so it gets all of tmthread class variables?
why the need for separate tmthread.create and tmthread.execute 'objects'? (procedure tmthread.create and consturctire tmthread.create ?)
can they be combined into one constructor/procedure?
and what the inherited create(false) really means.
public constructor TThread.Create(
CreateSuspended: Boolean;
const StackSize: SizeUInt = DefaultStackSize
);
in the example multithreainexample1 (which compiles and runs on my machine btw)
the /usr/local/lazarus/examples/multithreading/mainunit.pas
has constructor Create(CreateSuspended: boolean);
mine is constructor tmthread.create(c : longint); how come i don't have any problem passing the parameter c which is the loop/thread number?
so constructor line is like a procedure line - i thought it was a static thing
are t.terminate; and t.destroy not needed in my case since the threads end on their own in wf() which ends after loop is done?
at the end to keep program alive until all threads are finish - what do you use?
probably best for me to just appreciate what goes on behind the scenes and be glad it worksYeah, I'm like that too: Take some quite time to read the docs and get at least a general view, be glad it works ... and then thank the gods I'm not the one that has to make it work! :D
Quoteprobably best for me to just appreciate what goes on behind the scenes and be glad it worksYeah, I'm like that too: Take some quite time to read the docs and get at least a general view, be glad it works ... and then thank the gods I'm not the one that has to make it work! :D
The default stacksize for threads -in windows- is 4 megabytes.
this works - if i have a real delay finishing the wf thread then the threads get totally unique threadid but if there is no delay in it finishing then the code seems to reuse threadid in alternate threads (the system tries to conserve resources?)It totally depends on the operating system whether it reuses thread IDs, but it is definitely free to do so, so you shouldn't rely on the thread ID if you create many short lived threads.
aren't all threads freed automatically when the main program ends?It depends on the operating system whether the program ends when the main thread returns or only ends if all threads terminated. Also in your example it might not matter, but in more complex cases you might want the threads to finish gracefully (maybe one is currently writing in a file / to a database?).
am i creating potential problem by not using private, protectd, public here?
i don't create units usually so don't know if they are really needed here or not
type tmthread = class(tthread)
// private
ch : longint;
// protected
procedure execute; override;
// public
constructor create(c : longint);
end;
It is also OS dependant. For example on Unix the information is not retrieved from the executable, but the environment. See the man page for pthread_create (http://man7.org/linux/man-pages/man3/pthread_create.3.html) (Notes section).The default stacksize for threads -in windows- is 4 megabytes.
Actually, it is dependent on compiler settings, not the OS. The PE header of an executable specifies the stack size. That value gets set to whatever you configure your compiler to generate. But an application's code can override that size at runtime by calling the Win32 CreateThread() or the RTL's BeginThread() directly.
aren't all threads freed automatically when the main program ends?It depends on the operating system whether the program ends when the main thread returns or only ends if all threads terminated. Also in your example it might not matter, but in more complex cases you might want the threads to finish gracefully (maybe one is currently writing in a file / to a database?).
...you can create more threads. However, your application will have better performance if you create one thread per processor and build queues of requests for which the application maintains the context information. A thread would process all requests in a queue before processing requests in the next queueSecond. The thread object is created immediately in the constructor (the "Handle" property is available), so calling Sleep(1000) after creation looks strange.
another case of no good examples or code examples on the internet :
i see in a number of places that it isn't recommended to use external threads with fpc like in this (badly formulated function example)
function ethread(i: cint): clong; cdecl; external 'pthread';
so can be able to use the c thread functions like pthread_create( pthread_join( etc
i've used other c extern coding and wonder why this particular usage is frowned on?
Very basically, sleep(X) tells the system to suspend the process for at least the next X milliseconds. When X is 0 it means the process just relinquishes the rest of its currently alloted time-slice.You mean thread, not process. In this case it's an important difference. ;)
Hi Toby, lover of lowercase characters and hater of punctuation marks ;D
The first note is about the number of threads. Better to quote a phrase from the Microsoft documentation, I think it is still relevant for *nix:Quote...you can create more threads. However, your application will have better performance if you create one thread per processor and build queues of requests for which the application maintains the context information. A thread would process all requests in a queue before processing requests in the next queue
There is a caveat: Modern CPUs use dynamic clock rates. If more than one or two core runs they throttle the clock rate to avoid too much heat ;-)Yes, I ran into that with the Raspberry Pi 4: if you max out the cores it throttles down if the temp is higher than 80c. A heat sink set solved that. Even a passive one.
Microsoft instantiates thousands of threads when Windows starts...But that doesn't mean that they're all running all the time - otherwise the Task Manager would show more activity. Most threads are just waiting for a handle (from an event, from a file, another thread, another process, etc.) to be triggered before they do some work and then wait again.
A heat sink set solved that. Even a passive one.
A simple to use reference counted solution that you may want to look at OP is ezthreads. It lets you define the thread's behavior and settings (timeout, etc..) in a fluent way, and comes with Await functionality similar to c#
I've written some previous posts here:
https://forum.lazarus.freepascal.org/index.php/topic,44274.msg311176.html#msg311176
You may find use in ezthreads, either by using it as an alternative to standard tthread, or by seeing how I implemented some of the features (uses tthread under the hood)
Here's a link to several examples/use cases,
https://github.com/mr-highball/ezthreads/blob/master/test/ezthreads_tester.lpr
And here's previous post of mine,
A simple to use reference counted solution that you may want to look at OP is ezthreads. It lets you define the thread's behavior and settings (timeout, etc..) in a fluent way, and comes with Await functionality similar to c#
I've written some previous posts here:
https://forum.lazarus.freepascal.org/index.php/topic,44274.msg311176.html#msg311176
There is a caveat: Modern CPUs use dynamic clock rates. If more than one or two core runs they throttle the clock rate to avoid too much heat ;-)
Are there functional programming methods in Pascal such as map, filter, apply, reduce, fold, foldl and foldr function? I could not find them on searching the internet. Possibly Pascal is a purely imperative language.
If not, is it possible to create a map function so that one can sent a list/array to it with a function and it return a new list/array with sent function applied to each element of sent list:
outlist := map(sentfunction, sentlist);
where sentfunction is a function which takes only one item and returns a modified item.
The functional unit needs the latest trunk (3.3.1) to properly work, is that what you are using? If so what operating system?Did you also test with the upcoming 3.2? After all that's going to be the next major release containing generic functions as well.
(I also wrote it pretty quickly... So there are probably bugs)