First, the Windows version

Article source: blog.csdn.net/great3779/a…

1. Restrictions on creating threads in the process

By default, the stack of a thread reserves 1M memory space, while the available memory of a process is only 2G, so a maximum of 2048 threads can be opened in a process, but of course memory cannot be used as the stack of threads, so the actual number is smaller than this value.

 

 

[cpp] view plaincopy

  1. #include “stdafx.h”  
  2. #include <windows.h>  
  3. #include <process.h>  
  4. #include <assert.h>  
  5.   
  6. volatile bool gbExitThread = false;  
  7. HANDLE ghDataEvent = CreateEvent(NULL, FALSE, FALSE, NULL);  
  8.   
  9. UINT WINAPI SubThread(void* ptr)  
  10. {  
  11.     int nThreadID = *((int*)ptr);  
  12.     nThreadID++;  
  13.     SetEvent(ghDataEvent);  
  14. Printf (“%d thread start /n”, nThreadID);
  15.     int i = 0;  
  16. while(! gbExitThread)
  17.     {  
  18.         Sleep(10000);  
  19.     }  
  20.   
  21.     return 0;  
  22. }  
  23.   
  24. int _tmain(int argc, _TCHAR* argv[])  
  25. {  
  26.     int nThreadCount = 10000;  
  27.     HANDLE* phaThread = new HANDLE[nThreadCount];  
  28.     int nErr = 0;  
  29.     for(int i = 0; i < nThreadCount; i++)  
  30.     {  
  31.         phaThread[i] = (HANDLE)_beginthreadex(NULL, 0, SubThread, &i, 0, NULL);  
  32.   
  33.         if(phaThread[i] == 0)  
  34.         {  
  35.             nErr = GetLastError();  
  36.             if(nErr == 8)  
  37.             {  
  38. Printf (” Failed to start thread, insufficient storage space! /n”);
  39.             }  
  40.             else  
  41.             {  
  42. Printf (” failed to start thread, error number %d/n”, nErr);
  43.             }  
  44.   
  45.             break;  
  46.         }  
  47.   
  48.         WaitForSingleObject(ghDataEvent, INFINITE);  
  49.     }  
  50.   
  51.     return 0;  
  52. }  

 

 

 

2. How to break the 2000 limit? You can also change the default stack size at connect time to make it smaller so that more threads can be opened. If you change the default stack size to 512K, you can theoretically open up to 4096 threads. Even with large physical memory, the number of threads that can be started in a process is always limited by 2GB of memory. Let’s say your machine has 64GB of physical memory, but you still have 4GB of memory per process, with 2GB available in user mode.

If it is in the same machine, the number of threads is also limited by memory. Each thread object has to stand on non-page memory, which is also limited, and when non-page memory is used up, threads cannot be created.

If physical memory is very large, the limit on the number of threads that can run on the same machine becomes larger and larger.

 

MSDN: the original

“The number of threads a process can create is limited by The available virtual memory. By default, every thread has one megabyte of stack space. Therefore, If you reduce the default stack size, 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.”

 

The thread stack StackSize can be reduced by modifying the CreateThread parameter, for example

 

[cpp] view plaincopy

  1. #include “stdafx.h”  
  2. #include <windows.h>  
  3. #include <process.h>  
  4. #include <assert.h>  
  5.   
  6. volatile bool gbExitThread = false;  
  7. HANDLE ghDataEvent = CreateEvent(NULL, FALSE, FALSE, NULL);  
  8.   
  9. UINT WINAPI SubThread(void* ptr)  
  10. {  
  11.     int nThreadID = *((int*)ptr);  
  12.     nThreadID++;  
  13.     SetEvent(ghDataEvent);  
  14. Printf (“%d thread start /n”, nThreadID);
  15.     int i = 0;  
  16. while(! gbExitThread)
  17.     {  
  18.         printf(“%d: %d/n”, nThreadID, i++);  
  19.         Sleep(10000);  
  20.     }  
  21.   
  22. Printf (“%d thread exit /n”, nThreadID);
  23.   
  24.     return 0;  
  25. }  
  26.   
  27. int _tmain(int argc, _TCHAR* argv[])  
  28. {  
  29.     int nThreadCount = 10000;  
  30.     HANDLE* phaThread = new HANDLE[nThreadCount];  
  31.     int nErr = 0;  
  32.     for(int i = 0; i < nThreadCount; i++)  
  33.     {  
  34.         phaThread[i] = (HANDLE)_beginthreadex(NULL, 512*1024, SubThread, &i, STACK_SIZE_PARAM_IS_A_RESERVATION, NULL);  
  35.         if(phaThread[i] == 0)  
  36.         {  
  37.             nErr = GetLastError();  
  38.             if(nErr == 8)  
  39.             {  
  40. Printf (” Failed to start thread, insufficient storage space! /n”);
  41.             }  
  42.             else  
  43.             {  
  44. Printf (” failed to start thread, error number %d/n”, nErr);
  45.             }  
  46.   
  47.             break;  
  48.         }  
  49.   
  50.         WaitForSingleObject(ghDataEvent, INFINITE);  
  51.     }  
  52.   
  53.     return 0;  
  54. }  

 

 

 

 

Server-side programming

If your server-side program is designed to create a thread for each client connection request, then there is a limit of 2000 (for a given number of hardware memory and CPUS). The suggestions are as follows:

The “one thread per client” model is well-known not to scale beyond a dozen clients or so. If you’re going to be handling more than that many clients simultaneously, you should move to a model where instead of dedicating a thread to a client, you instead allocate an object. (Someday I’ll muse on the duality between threads and objects.) Windows provides I/O completion ports and a thread pool to help you convert from a thread-based model to a work-item-based model.

1. Serve many clients with each thread, and use nonblocking I/O and level-triggeredreadiness notification

2. Serve many clients with each thread, and use nonblocking I/O and readiness changenotification

3. Serve many clients with each server thread, and use asynchronous I/O

Use asynchronous I/O, and one thread to handle multiple customer requests!!

 

Second, Linux version

Blog.csdn.net/hhhanpan/ar…

Recently, I was working on a chat server project, where I encountered a problem: how many threads can a process produce?

At the beginning, all kinds of imagination will be related to different platforms and different systems. Many online bigwigs say there are 1024, but there are also 256.

Instead of guessing, try it out. Test on Linux 32-bit platform.

 

 
Copy the code
  1. 1 #include <stdio.h>
  2. 2 #include <unistd.h>
  3. 3 #include <iostream>
  4. 4 #include <stdlib.h>
  5. 5 #include <string.h>
  6. 6 #include <pthread.h>
  7. 7 #include <errno.h>
  8. 8
  9. 9 using namespace std;
  10. 10 // Test how many threads can a process start??
  11. 11
  12. 12 void *thread_function(void *arg);
  13. 13
  14. 14 char message[] = "Hello world";
  15. 15
  16. 16 int main()
  17. 17 {
  18. 18 int res;
  19. 19 pthread_t a_thread;
  20. 20 int i = 0;
  21. 21
  22. 22 while( 1 )
  23. 23 {
  24. 24 // Create a thread
  25. 25 res = pthread_create(&a_thread, NULL, thread_function, (void *)messa ge);
  26. 26 i++;
  27. 27 if( res ! = 0)
  28. 28 {
  29. 29 cout<<" number of threads: "<< I <<endl;
  30. 30 perror("Thread creation failed; errno:");
  31. 31 return 0;
  32. 32}
  33. 33}
  34. 34}
  35. 35
  36. 36 void *thread_function(void *arg)
  37. {37
  38. 38 printf("thread_function is runing.Argument is %s\n", (char*)arg);
  39. 39}

 

 

 

It might look a little rough, but after repeated testing, it produced about 304 threads.

On the 32-bit Linux platform, the virtual memory space is 4G, the user space is 3G, and the kernel space is 1G. The stack size of each thread is 10240, which is 10M, 3072/10=307. Remove the main thread and approach the test data.

To view the default stack size, run the ulimit -s or ulimit -a command

Of course, you can temporarily change the thread stack size by using the ulimit -s+ command

The number of threads increased after the thread stack was modified.