我有一个案例,需要只调用一次特定的API来初始化 . 此后线程可以调用其他方法 . 在vuser_init.c中,我有这个:
static volatile int initOnlyOnce = 0;
static volatile int initComplete = 0;
int iStatus;
if (1!=initOnlyOnce ) {
initOnlyOnce =1;
lr_output_message("Before, initComplete = %d", initComplete );
iStatus = Initialize(); // product API call
initComplete = 1;
lr_output_message("After, initComplete = %d", initComplete );
if (1 != iStatus ) {
lr_error_message("Initialize returns %d on %s.",iStatus,szLoadGenerator);
srand(time(NULL));
}
}
当我运行场景时,第一个线程打印两个,即
Before, initComplete = 0
其次是
After, initComplete = 1
并且正确地在该线程中完成测试的其余部分 . 但是,下一个线程失败并显示“错误 - 内存冲突:收到异常ACCESS_VIOLATION”,因为它已执行后续方法而没有初始化完成或initComplete为0.每个其他线程的日志都有“之前,initComplete = 0 “作为最后一行 . 由于我已将这些变量定义为静态volatile,我预计会这样做
initOnlyOnce = 1
在第一个线程调用它之后,随后不再输入这个代码块 . 然而,似乎Vugen与线程不同 . 每个vuser_init.c独立于其他Vugens运行,因此虽然变量被声明为静态volatile,但状态不会共享 .
有解决方法吗?我基本上想要一个vuser_init的单例前体 .
2 回答
我只想使用虚拟用户号变量并检查数字是否为1 .
PCODE(在init中)
If(虚拟用户变量的值== 1){运行初始化代码; }
因此,您需要创建变量,然后可能只分配一个虚拟用户来处理初始化然后退出 . 将此用户单独放在一个组中,然后甚至可以在其他用户启动之前退出 .
如果您愿意,可以添加计划在VUSER_INIT()之前启动的其他功能 . 在右侧的函数列表中添加函数,然后进入运行时设置并安排函数在vuser_init()之前运行一次 .
LoadRunner执行虚拟用户的方式并不那么容易理解,更不用说你应该依赖的东西了 .
在大多数情况下,vu在特殊的MMDRV进程下作为线程运行 . MMDRV进程运行大约50个线程,然后LR引擎启动另一个MMDRV进程,该进程再次运行50个线程 . (您也可以将VUsers作为一个进程运行,查看运行时设置) .
此外,如果您的测试中有LoadGenerators,这些正在不同的计算机上执行,并且无法知道在其他计算机上运行了多少个vuser .
正如James所说,如果你想在代码中使用VUserID作为"check"是最好的选择 . 要将VUserID作为名为"VUserID"的新参数获取,并选择类型为VUserID . 然后,您可以像使用任何其他参数一样使用
lr_eval_string("{VUserID}")
.另一种选择是在首先执行一个脚本然后执行其他脚本的模式下运行场景 .