DESCRIPTION
The pthread_create() function is used to create a new thread, with
attributes specified by attr, within a process. If attr is NULL, the
default attributes are used. If the attributes specified by attr are
modified later, the thread’s attributes are not affected. Upon success-
ful completion pthread_create() will store the ID of the created thread
in the location specified by thread.
The thread is created executing start_routine with arg as its sole argu-
ment. If the start_routine returns, the effect is as if there was an
implicit call to pthread_exit() using the return value of start_routine
as the exit status. Note that the thread in which main() was originally
invoked differs from this. When it returns from main(), the effect is as
if there was an implicit call to exit() using the return value of main()
as the exit status.
Upon thread exit the storage for the thread must be reclaimed by another
thread via a call to pthread_join(). Alternatively, pthread_detach() may
be called on the thread to indicate that the system may automatically
reclaim the thread storage upon exit. The pthread_attr_setdetachstate()
function may be used on the attr argument passed to pthread_create() in
order to achieve the same effect as a call to pthread_detach() on the
newly created thread.
The signal state of the new thread is initialized as:
o The signal mask is inherited from the creating thread.
o The set of signals pending for the new thread is empty.
RETURN VALUES
If successful, the pthread_create() function will return zero. Otherwise
an error number will be returned to indicate the error.
ERRORS
The pthread_create() function will fail if:
[EAGAIN] The system lacked the necessary resources to create
another thread, or the system-imposed limit on the
total number of threads in a process
[PTHREAD_THREADS_MAX] would be exceeded.
[EPERM] The caller does not have appropriate permission to set
the required scheduling parameters or scheduling pol-
icy.
[EINVAL] The value specified by attr is invalid.
SEE ALSO
fork(2), pthread_attr(3), pthread_cancel(3), pthread_cleanup_pop(3),
pthread_cleanup_push(3), pthread_exit(3), pthread_join(3)
STANDARDS
The pthread_create() function conforms to ISO/IEC 9945-1:1996
(``POSIX.1’').
BSD March 15, 2014 BSD
So you see the three ways it fails: out of resources, wrong parameter or permissions.
I’m trying to have maybe 3 threads at most and they should all be over fairly quickly. I’m automating some actions in the background of my app. A timer launches the first thread and then from that thread, two new ones are created. This all should be complete quite quickly.
On my MacBookPro, this works flawlessly. No issues. On an older MacMini (i5 CPU), I get the crash. But I have another MacMini also with an i5 and I’ve not seen the issue.
This has to be API2.0 related as I’ve spawned 10 to 15 threads in the past with no problem at all using Aaron Ballman’s thread pool manager.
No idea on the stack size. Again, there’s not a ton of processing going on. There’s just some things where I need to add delays and that’s really convenient to do in threads. I had been doing that by using timers but I was getting reports from customers of stuff not working right.
I have what is effectively a remote control with a number of buttons on one of my windows. When the user presses one of these buttons, it launches a thread that sends commands to other devices over the network. Basically, turn a TV on, play a DVD player, etc.
I have a class that does all this.
But this can also be automated and completely done in code. So a user can schedule a button to be “pressed” at a specific time. So there’s another object that is scheduled that ends up “pressing” this button in code. And this AutomationObject as I am calling it can “press” multiple buttons and do multiple other functions in the app. So it’s not really possible to do them in the same thread.
OK. Something really, really weird is happening. Maybe I have something mucked up in my code. I tried running it but with the first object running from a timer instead of a thread. The application hung and when I looked at the crash report, it had a huge number of repeats of method calls.
So I decided to open activity viewer and look at the number of threads being created when I am using the thread to do the action. It shot up to 4096! No wonder it is crashing.
However, running the EXACT SAME build with the exact same settings, etc. on my MacBookPro, I generate no excessive threads.
I am stumped. I am going to perform a remote debugging session on that machine to see why it is basically going into an infinite loop.
Looks like this is an issue with my code that is basically spawning all these threads. I figured out the difference between the two machines in what was being done in what I was scheduling. There was one slight difference and I’ve been able to duplicate it.
Still Xojo should throw an exception as it is really similar to a stack overflow.
Yup. I figured it out. I had a bug in my code that could potentially cause the object I am running in the thread to basically re-execute itself in an infinite loop. It only happens in specific instances depending on what I was scheduling to happen. Pretty significant bug that is now fixed! Whew!
This could have been less than the number of threads, but, indeed, this is the index of the crashing thread, starting at 0, so there were at least this number of threads created (which looks really weird when you read it).
You made your first fork bomb, congratulations
I’m not sure Xojo observes the thread count, in fact.
StackOverflow exceptions come from the OS, which has a small memory to handle method calls (a pointer to the caller method (where to resume later, etc.) and such), and, if that memory is full and you try to call one more method, the StackOverflow exception is triggered (somewhat equivalent to an OutOfMemory exception).
I don’t know whether too many threads running can be handled as an exception by Xojo…