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.
Related
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.
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
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;
}
I used one of the minimise to tray VC++ examples to create a program that would pop up a message at intervals to remind me to rest my eyes.
The program goes like this:
startTime = time(0);
g_hInstance=hInstance;
HWND hWnd=CreateDialog(hInstance,MAKEINTRESOURCE(IDD_DIALOG1),NULL,DialogProc);
if(hWnd)
{
MSG msg;
_beginthread(&checkEyeRestTime, 0, 0);
while(GetMessage(&msg,hWnd,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
and the checkEyeRestTime function:
void checkEyeRestTime(void* ptr)
{
while( true )
{
//logic to check time and display message
}//while
_endthread();
}
But this program takes up 50% CPU on a two core processor. How can I reduce the load on the processor?
Or insert Sleep(0) in the thread. This allows other threads to get some time.
If this does not help, you can increase sleep time.
Use a timer event instead of the polling loop.
I have a problem in understanding how the winapi condition variables work.
On the more specific side, what I want is a couple of threads waiting on some condition. Then I want to use the WakeAllConditionVariable() call to wake up all the threads so that they can do work. Besides the fact that i just want the threads started, there isn't any other prerequisite for them to start working ( like you would have in an n producer / n consumer scenario ).
Here's the code so far:
#define MAX_THREADS 4
CONDITION_VARIABLE start_condition;
SRWLOCK cond_rwlock;
bool wake_all;
__int64 start_times[MAX_THREADS];
Main thread:
int main()
{
HANDLE h_threads[ MAX_THREADS ];
int tc;
for (tc = 0; tc < MAX_THREADS; tc++)
{
DWORD tid;
h_threads[tc] = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)thread_routine,(void*)tc,0,&tid);
if( h_threads[tc] == NULL )
{
cout << "Error while creating thread with index " << tc << endl;
continue;
}
}
InitializeSRWLock( &cond_rwlock );
InitializeConditionVariable( &start_condition );
AcquireSRWLockExclusive( &cond_rwlock );
// set the flag to true, then wake all threads
wake_all = true;
WakeAllConditionVariable( &start_condition );
ReleaseSRWLockExclusive( &cond_rwlock );
WaitForMultipleObjects( tc, h_threads, TRUE, INFINITE );
return 0;
}
And here is the code for the thread routine:
DWORD thread_routine( PVOID p_param )
{
int t_index = (int)(p_param);
AcquireSRWLockShared( &cond_rwlock );
// main thread sets wake_all to true and calls WakeAllConditionVariable()
// so this thread should start doing the work (?)
while ( !wake_all )
SleepConditionVariableSRW( &start_condition,&cond_rwlock, INFINITE,CONDITION_VARIABLE_LOCKMODE_SHARED );
QueryPerformanceCounter((LARGE_INTEGER*)&start_times[t_index]);
// do the actual thread related work here
return 0;
}
This code does not do what i would expect it to do. Sometimes just one thread finishes the job, sometimes two or three, but never all of them. The main function never gets past the WaitForMultipleObjects() call.
I'm not exactly sure what I've done wrong, but I would assume some synchronization issue somewhere ?
Any help would be appreciated. (sorry if I re-posted older topic with different dressing :)
You initialize the cond_rwlock and start_condition variables too late. Move the code up, before you start the threads. A thread is likely to start running right away, especially on a multi-core machine.
And test the return values of api functions. You don't know why it doesn't work because you never check for failure.