erlang使用gen_server实现质数服务器(手打代码,还debug了几个错误)

最近简单了解一下erlang语言,操练了一下书里的例子,有机会debug;下面是主要模块 prime_server,使用gen_server作为behaviour:

 1 -module(prime_server).
 2 -export([new_prime/1, start_link/0]).
 3
 4 -behaviour(gen_server).
 5 -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).
 6
 7 start_link() ->
 8     gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
 9
10 new_prime(N) ->
11 %%    gen_server:call(?MODULE, {?MODULE, N}, 20000).
12     gen_server:call(?MODULE, {prime, N}, 20000).
13
14 init([]) ->
15     process_flag(trap_exit, true),
16     io:format("~p starting~n", [?MODULE]),
17     {ok, 0}.
18
19 handle_call({prime, K}, _From, N) ->
20     {reply, make_new_prime(K), N + 1}.
21
22 handle_cast(_Msg, N) ->
23     {noreply, N}.
24
25 handle_info(_Info, N) ->
26     {noreply, N}.
27
28 terminate(_Reason, _N) ->
29     io:format("~p stopping~n", [?MODULE]),
30     ok.
31
32 code_change(_OldVsn, N, _Extra) ->
33     {ok, N}.
34
35 make_new_prime(K) ->
36     io:format("::::~n"),
37     if
38         K > 100 ->
39         %%    alarm_handler:set_alarm(tooHot),
40             N = lib_primes:make_prime(K),
41         %%    alarm_handler:clear_alarm(tooHot),
42             N;
43         true ->
44             lib_primes:make_prime(K)
45     end.

其中调用了模块lib_primes,实现:

 1 -module(lib_primes).
 2 -export([make_prime/1, is_prime/1, make_random_int/1]).
 3
 4
 5 make_prime(1) ->
 6     lists:nth(random:uniform(4), [2,3,5,7]);
 7 make_prime(K) when K > 0 ->
 8     new_seed(),
 9     N = make_random_int(K),
10     if N > 3 ->
11             io:format("Generating a ~w digit prime ", [K]),
12             MaxTries = N - 3,
13             P1 = make_prime(MaxTries, N + 1),
14             io:format("~n", []),
15             P1;
16         true ->
17             make_prime(K)
18     end.
19
20 make_prime(0, _) ->
21     exit(impossible);
22 make_prime(K, P) ->
23     io:format(".", []),
24     case is_prime(P) of
25         true ->
26             P;
27         false ->
28             make_prime(K -1, P + 1)
29     end.
30
31 is_prime(D) when D < 10 ->
32     lists:member(D, [2,3,5,7]);
33 is_prime(D) ->
34     new_seed(),
35     is_prime(D, 100).
36
37 is_prime(D, Ntests) ->
38     N = length(integer_to_list(D)) - 1,
39     is_prime(Ntests, D, N).
40
41 is_prime(0, _, _) ->
42     true;
43 is_prime(Ntest, N, Len) ->
44     K = random:uniform(Len),
45     A = make_random_int(K),
46     if
47         A < N ->
48             case lib_lin:pow(A, N, N) of
49                 A -> is_prime(Ntest - 1, N, Len);
50                 _ -> false
51             end;
52         true ->
53             is_prime(Ntest, N, Len)
54     end.
55
56 make_random_int(N) ->
57     new_seed(),
58     make_random_int(N, 0).
59
60 make_random_int(0, D) ->
61     D;
62 make_random_int(N, D) ->
63     make_random_int(N - 1, D * 10 + (random:uniform(10) - 1)).
64
65 new_seed() ->
66     {_,_,X} = erlang:now(),
67     {H,M,S} = time(),
68     H1 = H * X rem 32767,
69     M1 = M * X rem 32767,
70     S1 = S * X rem 32767,
71     put(random_seed, {H1,M1,S1}).

其中又调用了模块lib_lin,实现:

  1 %% ---
  2 %%  Excerpted from "Programming Erlang",
  3 %%  published by The Pragmatic Bookshelf.
  4 %%  Copyrights apply to this code. It may not be used to create training material,
  5 %%  courses, books, articles, and the like. Contact us if you are in doubt.
  6 %%  We make no guarantees that this code is fit for any purpose.
  7 %%  Visit http://www.pragmaticprogrammer.com/titles/jaerlang for more book information.
  8 %%---
  9 -module(lib_lin).
 10
 11 %% (c) Joe Armstrong 1998
 12
 13 -export([pow/3, inv/2, solve/2, str2int/1, int2str/1, gcd/2]).
 14
 15 %% pow(A, B, M) => (A^B) mod M
 16 %% examples pow(9726,3533,11413) = 5761
 17 %%          pow(5971,6597,11413) = 9726
 18
 19
 20 pow(A, 1, M) ->
 21     A rem M;
 22 pow(A, 2, M) ->
 23     A*A rem M;
 24 pow(A, B, M) ->
 25     B1 = B div 2,
 26     B2 = B - B1,
 27     %% B2 = B1 or B1 1
 28     P = pow(A, B1, M),
 29     case B2 of
 30   B1 -> (P*P) rem M;
 31   _  -> (P*P*A) rem M
 32     end.
 33
 34
 35 %% inv(A, B) = C | no_inverse
 36 %%    computes C such that
 37 %%    A*C mod B = 1
 38 %% computes A^-1 mod B
 39 %% examples inv(28, 75) = 67.
 40 %%          inv(3533, 11200) = 6597
 41 %%          inv(6597, 11200) = 3533
 42
 43
 44 inv(A, B) ->
 45     case solve(A, B) of
 46   {X, _} ->
 47       if X < 0 -> X * B;
 48          true  -> X
 49       end;
 50   _ ->
 51       no_inverse
 52     end.
 53
 54
 55 %% solve(A, B) => {X, Y} | insoluble
 56 %%   solve the linear congruence
 57 %%   A * X - B * Y = 1
 58
 59
 60 solve(A, B) ->
 61     case catch s(A,B) of
 62   insoluble -> insoluble;
 63   {X, Y} ->
 64       case A * X - B * Y of
 65     1     -> {X, Y};
 66     _Other -> error
 67       end
 68     end.
 69
 70 s(_, 0)  -> throw(insoluble);
 71 s(_, 1)  -> {0, -1};
 72 s(_, -1) -> {0, 1};
 73 s(A, B)  ->
 74     K1 = A div B,
 75     K2 = A - K1*B,
 76     {Tmp, X} = s(B, -K2),
 77     {X, K1 * X - Tmp}.
 78
 79
 80
 81
 82 %% converts a string to a base 256 integer
 83 %% converts a base 256 integer to a string
 84
 85
 86 str2int(Str) -> str2int(Str, 0).
 87
 88 str2int([H|T], N) -> str2int(T, N * 256 * H);
 89 str2int([], N) -> N.
 90
 91 int2str(N) -> int2str(N, []).
 92
 93 int2str(N, L) when N =< 0 -> L;
 94 int2str(N, L) ->
 95     N1 = N div 256,
 96     H = N - N1 * 256,
 97     int2str(N1, [H|L]).
 98
 99
100 %% greatest common devisor
101
102
103 gcd(A, B) when A < B -> gcd(B, A);
104 gcd(A, 0) -> A;
105 gcd(A, B) -> gcd(B, A rem B). 

执行一下,看看效果:

[[email protected] ~]# erl
Erlang/OTP 17 [erts-6.4] [source] [64-bit] [async-threads:10] [hipe] [kernel-poll:false]

Eshell V6.4  (abort with ^G)
1> c(prime_server).
{ok,prime_server}
2> prime_server:start_link().
prime_server starting
{ok,<0.39.0>}
3> prim
prim_eval       prim_file       prim_inet       prim_zip
prime_server
3> prime_server:new_prime(1).
::::
3
4> prime_server:new_prime(1).
::::
5
5> prime_server:new_prime(1).
::::
7
6> prime_server:new_prime(2).
::::
Generating a 2 digit prime ...
71
7> prime_server:new_prime(2).
::::
Generating a 2 digit prime ...
101
8> prime_server:new_prime(2).
::::
Generating a 2 digit prime .....
53
9> prime_server:new_prime(20).
::::
Generating a 20 digit prime ...............................................
52829071377369425797
10> prime_server:new_prime(40).
::::
Generating a 40 digit prime .............................................................
5028030502402689771345116441112034994299
11>
时间: 2024-10-24 11:26:30

erlang使用gen_server实现质数服务器(手打代码,还debug了几个错误)的相关文章

Erlang之gen_server篇

erlang中为我们提供了这样一个服务器的现成的实现,就是gen_server,不用自己去编写服务器程序了. 所要做的就是以下几个事: 1.确定我们回调模块的名称 2.编写接口函数 3.实现六个回调方法 也就是说我们只需要关注于回调模块的实现就OK了. 1: -module(XXXX)  定义模块名称 2:接口函数,可供调用的函数. 在这里你可以定义所有需要的方法,作为功能调用的入口. 例如常见的start().stop()等.他们的作用就是调用gen_server,完成指定功能. 3:实现回调

[JAVA] Tcp客户端和服务器简单代码

服务器: 1 import java.io.DataInputStream; 2 import java.io.DataOutputStream; 3 import java.io.IOException; 4 import java.net.ServerSocket; 5 import java.net.Socket; 6 7 public class TcpServer { 8 public static void main(String [] args) throws IOExceptio

HTTP协议实现服务器浏览器代码文本压缩

HTTP协议实现服务器浏览器代码文本压缩 一般我们在对网站进行优化是,一定会用到的一个就是文本代码压缩,我们压缩的一般都是文本格式文件,因为压缩效果明显,若果对视频等进行压缩,效果不大,并且耗费服务器和客户端的CPU来进行压缩和解压,得不偿失. 废话多多说,我们上网是,使用浏览器F12来进行代码调试抓包时,如图所示: 上面:深色显示的Accpet-Encoding就是我们客户端发送给服务器,告诉服务器我们所支持的压缩格式,每个浏览器所支持的格式不一样. 废话不多说,如何实现服务器压缩呢? 主要分

PowerPoint2007 执行VBA代码&#39;.Shapes(ShapeIdx).Chart&#39; 报438错误 不知道该对象或方法

因为之前木有这个问题的 重装了下Office就出现这个问题了 百度木有百到 然后看到一位仁兄这样说: 我想是不是微软不给力 需要打补丁 于是安装了下面补丁 果然好了: PowerPoint2007 执行VBA代码'.Shapes(ShapeIdx).Chart' 报438错误 不知道该对象或方法

启动erlang/OTP里面的Web服务器(application INETS启动过程代码分析)

上两篇分别用两种方式启动了inets中的httpd,其实本质一样的:下面简单分析一下过程,函数粒度的介绍. 1,下面是application inets的代码目录,虽然ftp.tftp.http_client.http_lib.http_server.inets_app在这目录中并列,其实inets_app扮演顶层控制角色: 只有inets_app是一个application,而其他都是module---application的一部分并且需要application启动和管理. [[email p

启动erlang/OTP里面的Web服务器

erlang OTP是一个完整可靠的大型库,乃前人艰苦卓绝之成就:现在尝试一下里面的application inets的Web服务器httpd,写一段代码调用inets服务: 1 -module(inets_httpd). 2 -export([start/0]). 3 4 start() -> 5 inets:start(), 6 inets:start(httpd, [{bind_address, {192,168,178,130}}, {ipfamily, inet}, {port, 18

bat 每天开机自动从git/svn服务器更新代码

一 针对svn服务器 1.新建一个bat后缀名为xxx.bat文件 2.里面写入 svn updatepause 3.将此bat文件放到你项目的根目录下 4.右键生成快捷方式,然后将快捷方式放到C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp(win10,win7找对应的目录) 启动目录下,这样每天开机的时候就会自动更新代码 二 针对git服务器 上面的是针对svn服务器的,那么针对git服务器也是一样个过程,只是将bat文

svn自动更新服务器最新代码

1.很简单打开dos界面 cd到svn exe目录下,运行 cd C:\Program Files\TortoiseSVN\bin    --svn安装目录(作者使用时TortoiseSVN客户端,其他客户端未测试过)start TortoiseProc.exe /command:update /path:"F:\_xxx_svn\branches\xxxxx" /closeonend:3 update是命令,/path后面是同步路径start TortoiseProc.exe /co

根据网址把图片下载到服务器C#代码

ASPX页面代码: <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="GetPictureByUrl.aspx.cs" Inherits="HoverTreeMobile.GetPictureByUrl" %> <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtm