max number of threads Mac allows - multithreading

What is the maximum number of threads macOS allows before it reports errors? I can not find an easy answer for this. I believe it is 125, but how can I find this? Thanks for any help

As stated in my comment, this will obviously depend on the macOS version.
I don't know the exact limit, but macOS will definitely support more than 125 threads per process.
You can test this quite easily:
#import <Foundation/Foundation.h>
static NSLock * lock;
int main( void )
{
#autoreleasepool
{
lock = [ NSLock new ];
for( int i = 0; i < 10000; i++ )
{
[ NSThread detachNewThreadWithBlock: ^( void )
{
[ lock lock ];
NSLog( #"Thread %i", i );
[ lock unlock ];
while( 1 )
{
[ NSThread sleepForTimeInterval: 1 ];
}
}
];
}
while( 1 )
{
[ NSThread sleepForTimeInterval: 1 ];
}
}
return 0;
}
On my MacBookPro 2018, running macOS 10.14, I can spawn more than 8000 threads.
Real number is 8188.
Since there's a main thread, plus 3 threads dedicated to dispatch queues, we might assume the limit is 8192, which totally makes sense.
But still, this might depend on the hardware, number of CPUs/Cores.
As a side-note, if you are concerned about the maximum number of threads, then you shouldn't use threads.
Instead, use dispatch queues provided by Grand Central Dispatch (CGD):
dispatch_async
(
dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_HIGH, 0 ),
^( void )
{
/* ... */
}
);
You can obviously create your own serial or concurrent queues:
dispatch_queue_create( "MyQueue", DISPATCH_QUEUE_CONCURRENT );
On concurrent dispatch queues, this will let macOS manage the available resources, spawning new threads when it's OK to do so.
This is the way you should use concurrency. Try to forget about threads, and simply start using GCD.

Only 2048 threads per process. More attempts cause code 35 in pthread_create:
The thread limit can be increased to 5000 by activating the macOS server performance mode which was originally meant to be used with macOS Server machines.
To active, go to the Terminal app to enter
sudo nvram boot-args="serverperfmode=1 $(nvram boot-args 2>/dev/null | cut -f 2-)
and restart the computer.
To check if performance mode is active:
nvram boot-args
To deactivate:
sudo nvram boot-args="$(nvram boot-args 2>/dev/null | sed -e $'s/boot-args\t//;s/serverperfmode=1//')"
See also Turn on performance mode for macOS Server

Related

FreeRTOS stuck at prvCheckTasksWaitingTermination

I'm working with a Nucleo-STm32F767 and I had generated the code with CubeMX including FreeRTOS 9.
My code has 5 task and each task has a loop, where the task is suspended on each iteration.
while( 1 )
{
//Do something
osDelay(TASK_MAIN_DELAY_MS);
}
At this point my system works well.
Now I added a task that handle the communication with an SPI network controller. The network controller has it own middleware written in C.
Now every time I try to suspend a task (with osDelay) my code is stucked into prvCheckTasksWaitingTermination and my system is blocked forever.
static void prvCheckTasksWaitingTermination( void )
{
/** THIS FUNCTION IS CALLED FROM THE RTOS IDLE TASK **/
#if ( INCLUDE_vTaskDelete == 1 )
{
BaseType_t xListIsEmpty;
/* ucTasksDeleted is used to prevent vTaskSuspendAll() being called
too often in the idle task. */
while( uxDeletedTasksWaitingCleanUp > ( UBaseType_t ) 0U )
{
vTaskSuspendAll();
{
xListIsEmpty = listLIST_IS_EMPTY( &xTasksWaitingTermination );
}
( void ) xTaskResumeAll();
if( xListIsEmpty == pdFALSE )
{
TCB_t *pxTCB;
taskENTER_CRITICAL();
{
pxTCB = ( TCB_t * ) listGET_OWNER_OF_HEAD_ENTRY( ( &xTasksWaitingTermination ) );
( void ) uxListRemove( &( pxTCB->xStateListItem ) );
--uxCurrentNumberOfTasks;
--uxDeletedTasksWaitingCleanUp;
}
taskEXIT_CRITICAL();
prvDeleteTCB( pxTCB );
}
else
{
mtCOVERAGE_TEST_MARKER();
}
}
}
#endif /* INCLUDE_vTaskDelete */
In particular, the execution is stopped here: while( uxDeletedTasksWaitingCleanUp > ( UBaseType_t ) 0U ) becuase uxDeletedTasksWaitingCleanUp is equal to 0.
I don't know how to resolve this issue :(
Anybody can help me?
Thanks and best regards,
Federico
prvCheckTaskWaitingTermination is just part of the idle task. Unless you are running tickless operation it will just keep executing as long as no higher priority tasks are able to run. In your case I'm going to guess that the SPI driver is doing something that stops or masks the tick interrupt so time doesn't change, so delays never end. Just a guess though.
I'm not sure if this will help your issue, but I was running into this same problem and was able to get past it.
In my freertos.cpp file, I had several tasks executing in succession one after another. However, the second task was being executed but would fail each time because the peripheral it was trying to use was not working properly. It seems that since I did not have a catch for this, it was having trouble switching from the task.
Once I fixed the peripheral (in my case a cellular modem that was trying to connect to an unreachable server), the program executed properly and did not get stuck in this prvCheckTasksWaitingTermination function.
So, in your case, perhaps this indicates an issue with your SPI configuration that needs attention.
I hope this helps.

Terminating a thread CMSIS-RTOS

I'm currently trying to make my device (STM32F105) which is usually running 12 threads on CMSIS RTOS go to low power mode. In order to simplify the algorythm I think (definitely not sure) that it's a good idea to terminate all the threads using osThreadTerminate and after a wake up recreate them using osThreadCreate
void os_idle_demon (void) {
/* The idle demon is a system thread, running when no other thread is */
/* ready to run. */
for (;;) {
/* HERE: include optional user code to be executed when no thread runs.*/
if (Sleep.SleepEnabled == 1)
{
if (Sleep.IsSleeping == 1)
{
// __wfi();
// PWR_EnterSTOPMode(PWR_Regulator_ON, PWR_STOPEntry_WFI); //PWR_Regulator_LowPower
__nop();
// osDelay(5000);
if (Sleep.WakeUp)
{
Sleep.IsSleeping = 0;
WakeUp();
// SetSysClock();
Sleep.WakeUp = 0;
Sleep.SleepEnabled = 0;
Sleep.TimeTillSleep = 60;
}
}
else
{
if (Sleep.TimeTillSleep == 0 )
{
TerminateTasks();
ResetPeripherals();
Sleep.IsSleeping = 1;
// PWR_EnterSTANDBYMode();
// __wfi();
// PWR_EnterSTOPMode(PWR_Regulator_ON, PWR_STOPEntry_WFI);
__nop();
// osDelay(5000);
}
}
}
}
}
As you can see I use some global variables to determinte when to sleep. TerminateTasks(); is used to terminate all of my running threads using osThreadTerminate function which doesn't seem to cause any trouble, but after I call WakeUp(); which uses osThreadCreate function to recreate terminated threads I run into an os stack overflow. So there are a few questions I struggle to find answers to. Does osThreadTerminate command in CMSIS-RTOS release stack after execution? Is there a better way to go into a low power mode ? I hope I made my point clear, if there's a need to be more specific let me know. Would be grateful if you shared your experience with similar problems.
Do you use dynamic allocation in your other thread ? Because if so, killing your thread when there are running could result in memory leak.

All threads are executing at once

I try to find out the number of CPU cores using threads in C. Someone told me to try to execute 40 threads at once, make every thread sleep for one second, and see how many are executed simultaneously. I really like his approach, the problem is after executing my code, the program is sleeping for 1 second, and after that all threads are launced at once(no sleeping included).
Can someone please help me out?
void func(void* arg)
{
int n=(int*)arg;
sleep(1);
printf("Exec nr:%d\n",n);
}
int main(void) {
int i;
time_t rawtime;
struct tm * timeinfo;
time ( &rawtime );
timeinfo = localtime ( &rawtime );
printf ( "Current local time and date: %s", asctime (timeinfo) );
for(i=0;i<N;i++)
{
pthread_create(&th[i],NULL,func,(int*)i);
}
for(i=0;i<N;i++)
{
pthread_join(th[i],NULL);
}
time_t rawtime2;
struct tm* timeinfo2;
time ( &rawtime2 );
timeinfo2 = localtime ( &rawtime2 );
printf ( "Current local time and date: %s", asctime (timeinfo2) );
return 0;
}
You won't be able of discovering the number of CPUs in this way, because the scheduler may choose to run all your threads on the same core and leave the other cores for (more important) stuff.
Therefore, you should rely on some functionality provided by your OS.
For example, on Linux the file /proc/cpuinfo provides information about the CPU. This file can be opened and parsed by any user-level program. Other operating systems provide different mechanisms.

How to kill a thread from another thread in vala

I have a main thread which creates another thread to perform some job.
main thread has a reference to that thread. How do I kill that thread forcefully some time later, even if thread is still operating. I cant find a proper function call that does that.
any help would be appreciable.
The original problem that I want to solve is I created a thread a thread to perform a CPU bound operation that may take 1 second to complete or may be 10 hours. I cant predict how much time it is going to take. If it is taking too much time, I want it to gracefully abandon the job when/ if I want. can I somehow communicate this message to that thread??
Assuming you're talking about a GLib.Thread, you can't. Even if you could, you probably wouldn't want to, since you would likely end up leaking a significant amount of memory.
What you're supposed to do is request that the thread kill itself. Generally this is done by using a variable to indicate whether or not it has been requested that the operation stop at the earliest opportunity. GLib.Cancellable is designed for this purpose, and it integrates with the I/O operations in GIO.
Example:
private static int main (string[] args) {
GLib.Cancellable cancellable = new GLib.Cancellable ();
new GLib.Thread<int> (null, () => {
try {
for ( int i = 0 ; i < 16 ; i++ ) {
cancellable.set_error_if_cancelled ();
GLib.debug ("%d", i);
GLib.Thread.usleep ((ulong) GLib.TimeSpan.MILLISECOND * 100);
}
return 0;
} catch ( GLib.Error e ) {
GLib.warning (e.message);
return -1;
}
});
GLib.Thread.usleep ((ulong) GLib.TimeSpan.SECOND);
cancellable.cancel ();
/* Make sure the thread has some time to cancel. In an application
* with a UI you probably wouldn't need to do this artificially,
* since the entire application probably wouldn't exit immediately
* after cancelling the thread (otherwise why bother cancelling the
* thread? Just exit the program) */
GLib.Thread.usleep ((ulong) GLib.TimeSpan.MILLISECOND * 150);
return 0;
}

Perl Threads and Unsafe Signals

So I recently wanted to thread one of my Perl programs to increase its speed. Taking in a list of websites, I wanted to start a thread for each url and get the content of each website and then look for a company description on the page. Once one thread found a result, or all thread's didn't, I wanted to exit, write my result, and read in urls for my next company.
The problem that I see is that I use the Perl::Unsafe::Signals module inside of the function that I call when creating a thread. I need the unsafe signals to interrupt regular expressions that get "stuck". However this seems to cause all sorts of problems, mainly having the program crash and the error msg "Alarm Clock" shown.
Therefore, is there a way to use Perl::Unsafe::Signals and threads safely? Is there a way to timeout a regular expression in another way by sending a signal to the function ( like I send a 'KILL' signal below?) Thanks.
Note: I stripped down the code to all pertinent parts, let me know if you need more.
use threads ('exit' => 'threads_only');
use threads::shared;
my #descrip;
share(#descrip);
my $lock;
share($lock);
URL:foreach my $url(#unique_urls) {
#skip blank urls
if(!$url) { next URL; }#if
#find description
my $thread = threads->create(\&findCompanyDescription, $PREV_COMPANY, $PREV_BASE_URL, $url);
#while a description has not been found and there are still active threads, keep looking
#there may be a better way to do this, but this seems to work for me
while(!#descrip && threads->list() != 0) {;}
#kill all threads, write output, read in next batch of urls
my #threads = threads->list();
foreach(#threads) { print("detaching\n"); $_->kill('KILL')->detach(); }#foreach
#######SUBROUTINE CALLED BY THREAD CREATE
sub findCompanyDescription {
my($company_full, $base_url, $url) = #_;
my($descrip, $raw_meta, $raw) = '';
my #company;
$SIG{'KILL'} = sub { alarm(0); threads->exit(); };
eval {
local $SIG{ALRM} = sub { die("alarm\n") }; # NB: \n required
alarm(5);
use Perl::Unsafe::Signals;
UNSAFE_SIGNALS {
while($company) {
my #matches = ($content =~ m!.*<([\w\d]+).*?>\s*about\s+$company[\w\s\-_]*<.*?>(?:<.*?>|\s)*(.*?)</\1.*?>!sig);
MATCH:for(my $ndx=1; $ndx<#matches; $ndx+=2) {
($raw, $descrip) = &filterResult($matches[$ndx], $company_full);
if($descrip) {
$company = undef;
last(MATCH);
}#if
}#for
#reduce the company name and try again
$company = &reduceCompanyName($company);
}#while
alarm(0);
};#unsafe_signals
};#eval
if($#) {
if($# eq "alarm\n" && $DEBUG) { print("\nWebpage Timeout [].\n"); }#if
}#if
if($descrip) { lock($lock); {
#descrip = ($PREV_ID, $company_full, $base_url, $url, 1, $raw, $descrip); }
}#if
In general, "unsafe" signals are unsafe for both single threaded and multi-threaded. You've only increased your peril by using threads and unsafe signals. Perl's usual safe signal handler sets the flag signal_pending without meaningfull interrupting execution. The VM checks that flag when it's between opcodes.
Your regexp execution is a single, "atomic" opcode. Of course, the regexp itself is another VM with its own opcodes but we don't have currently visibility into that for the perl signal handler.
Frankly, I've no good idea about how to interrupt the regexp engine. It's got some global C state which in the past prior to perl-5.10 prevented it from being reentrant. It might not be safe for universal interruptability like you're trying. If you really wanted it to be fully interruptible, you might want to fork and have your child process do the regexp and communicate the results back over a pipe.
require JSON;
require IO::Select;
my $TIMEOUT_SECONDS = 2.5; # seconds
my ( $read, $write );
pipe $read, $write;
my #matches;
my $pid = fork;
if ( $pid ) {
my $select = IO::Select->new( $read );
if ( $select->can_read( $TIMEOUT_SECONDS ) ) {
local $/;
my $json = <$read>;
if ( $json ) {
my $matches_ref = JSON::from_json( $json );
if ( $matches_ref ) {
#matches = #$matches_ref;
}
}
}
waitpid $pid, 0;
}
else {
my #r = $content =~ m!.*<([\w\d]+).*?>\s*about\s+$company[\w\s\-_]*<.*?>(?:<.*?>|\s)*(.*?)</\1.*?>!sig;
my $json = JSON::to_json( \ #r );
print { $write } $json;
close $write;
exit;
}
IMHO, mixing signals and threads is a challenging task per se (i.e. w/o perl-specific things).
Remember that even in a single-threaded program you can safely call only async-signal-safe functions from the signal handler because the program may be interrupted at any point.
Perl adds another layer of abstraction, so I have no idea about safety of calling "die" from signal handler in case of unsafe signals.
If I remember properly, SIGALRM is asynchronous signal, so it must be handled synchronously. Your way of handling it is generally incorrect in multi-threaded programs.
Moreover, IMHO perl threads just do not work as most people expect.
Just avoid using them and use processes instead.
P.S.
The following line doesn't make sense:
$SIG{'KILL'} = sub { alarm(0); threads->exit(); };
SIGKILL (as well as SIGSTOP) cannot be caught.
I'm not really specialist on Perl-MT, but one thing you apparently is missing is that signals are global to the whole process - they are not thread specific. On POSIX systems you can't set a signal handler for a thread: signals are delivered to the whole process. IOW alarm() call affects the whole process, not only the thread which calls it. And even local %SIG in MT context doesn't do what one might think it does - because local is a thing of syntax.

Resources