51Testing软件测试论坛

标题: Rand函数在执行时带来的困惑 [打印本页]

作者: Athenst    时间: 2007-4-30 11:01
标题: Rand函数在执行时带来的困惑
这段代码在Genaration中执行时,每次输出的随机数都是正常的,范围在0-100之内,但是到Controller中执行,100用户,执行1次退出,得出的结果却非常的有规律;这是为什么?

百思不得其解,特来求助~

Action()
{
long file;
int rnd;
srand(time(NULL));
rnd = rand()%100;
if (rnd <= 50)
{
    file=fopen("c://1.txt","at+");
    fprintf(file,"%d\n", rnd);
    fclose(file);
}
else if (rnd > 50)
{
    file=fopen("c://1.txt","at+");
    fprintf(file,"%d\n", rnd);
    fclose(file);
}
return 0;
}


附件是某次执行完成后的结果。
作者: ireneyao    时间: 2007-4-30 11:24
关于随机函数,以前编程的时候接触过,这个函数如果单独使用,第一次取出的随机数基本都是固定的,而且这个固定的数和你的机器配置有关。顺着这个道理,我觉得你在Genaration中执行时,因为是连续执行,所以可以正常取随机数,但是在controller中,是同时执行,也就是说每个随机函数都是第一次调用,所以就出现随机数不随机的情况。
解决的办法,当时学c编程,是把系统时间和随机函数一起用,具体的我记不清啦,很久没用过这个函数了。大概描述一下哈,把系统时间转换成整型,乘以随机函数,这样每次调用就会不一样。
但是可能还会出现一个问题,因为是并发,就算微观不是并发,但是时间间隔仍然很短,如果用系统的秒相乘,可能大部分用户的秒还是一样的,如果能用毫秒(这个我没试过,如果不行,可以顺这个思路往下走),应该可以。

我的思路是这样的,如果有不对的,欢迎拍砖~~~~
斑竹不要说我误人子弟哈sdlkfj1

作者: Athenst    时间: 2007-4-30 11:55
楼上的解释我理解了,你说的完全正确~

刚看了Zee版的一篇文章,对Rand调用前的srand函数也明确了很多;
srand是给了rang函数一个种子,rand根据Srand提供的time进行随机取值,这一点可痛苦了。

既然是并发,那么在这个点上面的time值几乎是一致的,就算差也差不到哪儿去,所以随机值也有可能会落到某一小段范围内。

这和我最初想要的随机分配的初衷又违背了。
先去吃饭,下午来继续想问题。
作者: 麦子华华    时间: 2007-5-16 17:47
我也正迷惑这个问题,大家继续讨论啊,不能半途而废。
作者: shanxi    时间: 2007-5-16 18:28
是种子的问题

如果种子是个固定的或者种子的范围比较有规律 生成的随机数也同样

把种子取成系统当前的时间或者日期或者随时都不同的数字,比如GUID


srand((unsigned)time(NULL));
程序执行的CPU时间较快,调用time函数获取的时间精度却较低(55ms),这样循环体内每次产生随机数用到的种子数都是一样的,因此产生的随机数也是一样的。


srand((unsigned)timeGetTime());//产生随机数种子
这样可以使得每次产生的随机数序列不同。如果计算伪随机序列的初始数值(称为种子)相同,则计算出来的伪随机序列就是完全相同的。要解决这个问题,需要在每次产生随机序列前,先指定不同的种子,这样计算出来的随机序列就不会完全相同了。以time函数值(即当前时间)作为种子数,因为两次调用rand函数的时间通常是不同的,这样就可以保证随机性了。

这些都是伪随机数!
作者: mfktafd    时间: 2007-8-24 17:50
加入User id
lr_whoami(&id, &vuser_group, NULL);

把ID和随机数联起来就不一样了.


vuser_init()
{
int id;
char *vuser_group;
long file;
int rnd;
srand(time(NULL));
rnd = rand()%100;
lr_whoami(&id, &vuser_group, NULL);
if (rnd <= 50)
{
    file=fopen("c://1.txt","at+");
    fprintf(file,"%d", rnd);
    fprintf(file,"%d\n", id);
    fclose(file);
}
else if (rnd > 50)
{
    file=fopen("c://1.txt","at+");
    fprintf(file,"%d", rnd);
        fprintf(file,"%d\n", id);
    fclose(file);
}
        return 0;
}

[ 本帖最后由 mfktafd 于 2007-8-24 17:53 编辑 ]
作者: fish_yy    时间: 2007-8-24 21:44
sdlkfj3
作者: xuyan9927    时间: 2007-8-25 00:04
谢谢
作者: xuyan9927    时间: 2007-8-25 00:04
谢谢
作者: xuyan9927    时间: 2007-8-25 00:04
谢谢
作者: xuyan9927    时间: 2007-8-25 00:05
谢谢
作者: xuyan9927    时间: 2007-8-25 00:05
谢谢
作者: Athenst    时间: 2007-8-25 00:19
汗,楼上这谁灌水啊~
谢谢mfktafd ,
但是,
我假如想生成在0到100范围内的随机数呢?
作者: yabest    时间: 2007-8-25 01:09
原帖由 Athenst 于 2007-8-25 00:19 发表
汗,楼上这谁灌水啊~
谢谢mfktafd ,
但是,
我假如想生成在0到100范围内的随机数呢?


晕,楼主还是没看懂啊,srand只是用某个值初始化种子,不影响rand的取值范围的。
作者: Athenst    时间: 2007-8-25 13:28
原帖由 yabest 于 2007-8-25 01:09 发表


晕,楼主还是没看懂啊,srand只是用某个值初始化种子,不影响rand的取值范围的。


是的,我是还没懂~
要不你做一个结果来看看?

100个用户并发,每个用户生成一个0-100之间的随机数,写到一个txt文件里面去。

把脚本贴上来就可以了。
作者: mfktafd    时间: 2007-8-25 16:50
typedef long Clock_t;

Action()
{

//Clock_t time1;
long file;
int rnd;

   int id;
    char *vuser_group;
    double sin(double x) ;
float t,t1;
lr_whoami(&id, &vuser_group, NULL);
t=sin(id)*100000;

//取一个Id的Sin位置
t1=sin(clock())*100000;

//取一个开始计时的Sin位置
//time1=clock();

lr_rendezvous("111");

//lr_rendezvous(111);
srand(t+t1);

//这样Srand得到的值应该是比较随机的数值位置了.
//srand(time(NULL));
rnd = rand()%100;
//lr_output_message("%lf",sin(id));
if (rnd <= 50)
{
    file=fopen("c://1.txt","at+");
fprintf(file,"%lf : ",t+t1);
    fprintf(file,"%d\n", rnd);
    fclose(file);
}
else if (rnd > 50)
{
    file=fopen("c://1.txt","at+");
fprintf(file,"%lf : ",t+t1);
    fprintf(file,"%d\n", rnd);
    fclose(file);
}

return 0;
}
这个是我目前想到的最随机的方法了...


[ 本帖最后由 mfktafd 于 2007-8-28 10:51 编辑 ]
作者: Athenst    时间: 2007-8-25 17:08
嗯,谢谢mfktafd ~其实我想知道的就是种子的随机。

你现在的做法中,种子并不是随机的,所以导致了rand结果并不是0-100随机,假如打成图的话相信一定有某种规律曲线吧。

嗯,不过还是很佩服你的热心!

这帖子就不要跟了,请沉底。

[ 本帖最后由 Athenst 于 2007-8-25 17:17 编辑 ]
作者: fish_yy    时间: 2007-8-26 08:01
sdlkfj3
作者: ppent    时间: 2007-8-28 15:03
呵呵,我是用LR的随机参数来实现的,在controller中可以并发100用户可以生成0-100的随机数,不知道是否满足你的要求。

Action()
{
char* str;
long file;
int rnd;
srand(time(NULL));
rnd = rand()%100;
//abc是一个random类型的参数
lr_save_string(lr_eval_string("{abc}"),"str");


if (rnd <= 50)
{
    file=fopen("c://1.txt","at+");
    fprintf(file,"%d", rnd);
        fprintf(file,"                %s\n",lr_eval_string("{str}"));
    fclose(file);
}
else if (rnd > 50)
{
    file=fopen("c://1.txt","at+");
    fprintf(file,"%d", rnd);
        fprintf(file,"                %s\n",lr_eval_string("{str}"));
    fclose(file);
}
return 0;
}

[ 本帖最后由 ppent 于 2007-8-28 15:06 编辑 ]




欢迎光临 51Testing软件测试论坛 (http://bbs.51testing.com/) Powered by Discuz! X3.2