Erlang VM занимает около 600 OS / Windows машинных потоков - PullRequest
1 голос
/ 29 сентября 2019

я просто реализую простое приложение tcp listener / server в erlang, и я тестирую этот код, используя 40000 tcp соединений, и он создает около 600 os-потоков в windows-машине, и я закрыл эти 40K tcp-соединений, но erlang VM не освобождает 600 os / windows-потоков.Как я могу оптимизировать это, я с нетерпением жду вашего ответа


-module(tcptest).

%%
%% Include files
%%

%%
%% Defines
%%
-define(TCP_OPTIONS, [binary, {packet, raw}, {active, false}, {reuseaddr, true},{backlog,4000}]).

%%
%% Exported Functions
%%
-export([start/0,call/2,start_servers/1]).

%%
%% API Functions
%%
start() ->
    case gen_tcp:listen(8005, ?TCP_OPTIONS) of
        {ok, Socket} ->
            listen_loop(Socket);
        Error ->
            Error
    end.

%%
%% Local Functions
%%
listen_loop(Socket) -> 
    case gen_tcp:accept(Socket) of
        {ok, Sock} -> 
            io:format("Connection!~n"),
            spawn(fun() -> sock_loop(Sock) end);

        _ ->
            pass
        end,            
    listen_loop(Socket).



sock_loop(Sock) -> 
    case gen_tcp:recv(Sock, 0) of 
        {ok, Data} ->
            case handle_request(Sock, Data) of
                ok ->
                    sock_loop(Sock);
                exit ->
                    exit(normal)
            end;
        {error, Reason} ->
            gen_tcp:close(Sock),
            io:format("closed :  ~p~n",[Reason])
    end.

handle_request(Sock, Data) -> 
    case string:tokens(Data, "\r\n") of
        [String] when (String == "quit") ->
            exit;
        [String] ->
            gen_tcp:send(String, Sock),
            ok
    end.

1 Ответ

2 голосов
/ 30 сентября 2019

Реализация erl_poll в Windows (механизм, отвечающий за проверку новых данных в сокете) использует WaitForMultipleObjects.Этот API не позволяет использовать более 64 объектов на один вызов, поэтому erl_poll создает потоки, каждый из которых прослушивает 64 объекта.Это потоки, которые вы видите.

Не существует механизма, который удаляет эти потоки после их использования, поэтому они останутся до завершения работы системы.Они, конечно, повторно используются, если в будущем вы снова будете использовать такое количество соединений.

Код, который делает это, находится в: https://github.com/erlang/otp/blob/master/erts/emulator/sys/win32/erl_poll.c

...