windows 下一個程式能開多少個執行緒

smilestone322發表於2015-08-12

程式裡面建立執行緒數收到匯流排的限制,32位最多隻能訪問4G記憶體,其中2G為使用者態使用;而每個執行緒都有自己的棧大小;測試發現使用createthread建立執行緒;當棧設定為1M時,只能開大約1426個執行緒;當設定為512k時,可以開2244個執行緒,設定為256k時,可以開3122個執行緒,所以在我們做sock通訊伺服器時,需要注意,如果一個客戶端 connect進來,就用一個執行緒對它程式處理的話,服務端會收到執行緒數的限制;測試程式碼如下:

 

server

// server.cpp : 定義控制檯應用程式的入口點。
//

#include "stdafx.h"

#include <winsock2.h>
#include <stdio.h>
#include <list>
using namespace std;

#define STACK_SIZE 256*1024
#define MAX_COUNT  10000

bool stop=false;

DWORD WINAPI StartThreadFunc(PVOID pvParam)
{
   DWORD dwTid;
   printf("%-3d:0x%x\n",pvParam,&dwTid);
   while (!stop)
   {
	   Sleep(5000);
	  // printf("sock run\n");
   }
   return 0;
}

int _tmain(int argc, _TCHAR* argv[])
{

	// Initialize Winsock.
	if (argc<=2)
	{
		printf("param error\n");
		return 1;
	}

	const char *ip=argv[1];
	int port =atoi(argv[2]);

	WSADATA wsaData;
	int iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
	if (iResult != NO_ERROR) {
		printf("Error at WSAStartup()\n");
		return 1;
	}

	//----------------------
	// Create a SOCKET for listening for
	// incoming connection requests.
	SOCKET ListenSocket;
	ListenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	if (ListenSocket == INVALID_SOCKET) {
		printf("Error at socket(): %ld\n", WSAGetLastError());
		WSACleanup();
		return 1;
	}

	//----------------------
	// The sockaddr_in structure specifies the address family,
	// IP address, and port for the socket that is being bound.
	sockaddr_in service;
	service.sin_family = AF_INET;
	service.sin_addr.s_addr = inet_addr(ip);
	service.sin_port = htons(port);

	if (bind( ListenSocket, 
		(SOCKADDR*) &service, 
		sizeof(service)) == SOCKET_ERROR) {
			printf("bind() failed.\n");
			closesocket(ListenSocket);
			WSACleanup();
			return 1;
	}

	//----------------------
	// Listen for incoming connection requests.
	// on the created socket
	if (listen( ListenSocket, 1 ) == SOCKET_ERROR) {
		printf("Error listening on socket.\n");
		closesocket(ListenSocket);
		WSACleanup();
		return 1;
	}

	//----------------------
	// Create a SOCKET for accepting incoming requests.
	//SOCKET AcceptSocket;
	printf("Waiting for client to connect...\n");

	int clientNum=0;
	HANDLE m_hCommun[MAX_COUNT]={NULL};
	SOCKET sockNum[MAX_COUNT]={-1};

	while (clientNum<MAX_COUNT)
	{
		// Accept the connection.
		sockNum[clientNum] = accept( ListenSocket, NULL, NULL );
		if (sockNum[clientNum]  == INVALID_SOCKET) {
			printf("accept failed: %d,clientNum=%d\n", WSAGetLastError(),clientNum);
			closesocket(ListenSocket);
			WSACleanup();
			return 1;
		} else 
		{
		
		
			m_hCommun[clientNum] = CreateThread(NULL, STACK_SIZE, (LPTHREAD_START_ROUTINE)StartThreadFunc, (PVOID)clientNum, STACK_SIZE_PARAM_IS_A_RESERVATION, NULL);
			if (m_hCommun[clientNum]!=NULL)
			{
				printf("Client connected.clientNum=%d\n",clientNum);
			}
			clientNum=clientNum+1;
		}

	}
	//----------------------
	stop=true;

	for (int i=0;i<MAX_COUNT;i++)
	{
		if (sockNum[i]!=-1)
		{
			closesocket(sockNum[i]);
			sockNum[i]=-1;
		}

		if (m_hCommun[i]!=NULL)
		{
			CloseHandle(m_hCommun[i]);
			m_hCommun[i]=NULL;
		}
	}

	
	// No longer need server socket
	closesocket(ListenSocket);

	WSACleanup();
	printf("server exit\n");
	getchar();
	return 0;
}


client

// client.cpp : 定義控制檯應用程式的入口點。
//

#include "stdafx.h"
#include <stdio.h>
#include "winsock2.h"

#define MAX_COUNT  10000

int _tmain(int argc, _TCHAR* argv[])
{
	if (argc<=2)
	{
		printf("param error\n");
		return 1;
	}

	const char *ip=argv[1];
	int port =atoi(argv[2]);

	// Initialize Winsock
	WSADATA wsaData;
	int iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
	if (iResult != NO_ERROR)
	{
		printf("Error at WSAStartup()\n");
	}

	SOCKET ConnectSocket[MAX_COUNT]={-1};

    for (int i=0;i<MAX_COUNT;i++)
    {
		// Create a SOCKET for connecting to server

		ConnectSocket[i] = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
		if (ConnectSocket[i] == INVALID_SOCKET) {
			printf("Error at socket(): %ld\n", WSAGetLastError());
			WSACleanup();
			return 1;
		}

		//----------------------
		// The sockaddr_in structure specifies the address family,
		// IP address, and port of the server to be connected to.
		sockaddr_in clientService; 
		clientService.sin_family = AF_INET;
		clientService.sin_addr.s_addr = inet_addr(ip);
		clientService.sin_port = htons(port);

		//----------------------
		// Connect to server.
		if ( connect( ConnectSocket[i], (SOCKADDR*) &clientService, sizeof(clientService) ) == SOCKET_ERROR) {
			printf( "Failed to connect.\n" );
			WSACleanup();
			return 1;
		}

		printf("============sock connect succ=%d\n",i);

		Sleep(100);
    }

	for (int i=0;i<MAX_COUNT;i++)
	{
		if (ConnectSocket[i]!=-1)
		{
			closesocket(ConnectSocket[i]);
			ConnectSocket[i]=-1;
		}
	}

	printf("exit to server.\n");
	getchar();
	WSACleanup();
	return 0;
}


 

 

 

相關文章