czmq多个zactor实例崩溃
我试图使用czmq库中的zhash和zactor编写一个基本示例。我努力实现的主要目标是:czmq多个zactor实例崩溃,c,pthreads,zeromq,C,Pthreads,Zeromq,我试图使用czmq库中的zhash和zactor编写一个基本示例。我努力实现的主要目标是: 创建1024个zactor实例,并在每个actor创建之后发送“START”命令 等待参与者的响应以继续创建zactors 删除以前创建的所有参与者 我有点不明白为什么这个代码会中断。每次我到达演员编号60时,应用程序就会退出: ... ... 58 actor started! START command received! 59 actor started! START command receive
...
...
58 actor started!
START command received!
59 actor started!
START command received!
60 actor started!
> Assertion failed: (self), function zsock_set_sndtimeo, file
> src/zsock_option.c, line 1344.
> Abort trap: 6
编译:gcc-o demo.c-g-lczmq
代码如下:
#include <stdio.h>
#include <czmq.h>
typedef struct {
zsock_t *pipe; // Actor command pipe
zpoller_t *poller; // Socket poller
int terminated;
} accountactor_t;
typedef struct{
zactor_t *actor;
int foo;
} account_t;
accountactor_t *
accountactor_new (zsock_t *pipe, void *args)
{
accountactor_t *self = (accountactor_t *) zmalloc (sizeof (accountactor_t));
assert (self);
self->pipe = pipe;
self->poller = zpoller_new (self->pipe, NULL);
self->terminated = 0;
return self;
}
static void
accountactor_recv_api (accountactor_t *self)
{
// Get the whole message of the pipe in one go
zmsg_t *request = zmsg_recv (self->pipe);
if (!request){
return; // Interrupted
}
char *command = zmsg_popstr (request);
if (streq (command, "START")){
zsys_debug("START command received!");
zsock_signal (self->pipe, 0);
}else
if (streq (command, "STOP")){
zsys_debug("STOP command received!");
zsock_signal (self->pipe, 0);
}else
if (streq (command, "$TERM")){
zsys_debug("$TERM command received!");
// The $TERM command is send by zactor_destroy() method
self->terminated = 1;
}else {
zsys_error ("Invalid command '%s'", command);
zsock_signal (self->pipe, -1);
}
zmsg_destroy(&request);
if(command){
free(command);
}
}
void
actor_fcn (zsock_t *pipe, void *args)
{
accountactor_t * self = accountactor_new (pipe, args);
if (!self)
return; // Interrupted
int rc = 0;
// Signal actor successfully initiated
zsock_signal (self->pipe, 0);
while (!self->terminated) {
zsock_t *which = (zsock_t *) zpoller_wait (self->poller, -1);
if (which == self->pipe){
accountactor_recv_api (self);
}
}
if(zpoller_terminated(self->poller)){
zsys_debug("Poller Interrupted!");
}else
if(zpoller_expired(self->poller)){
zsys_debug("Poller Expired!");
}
// Free object itself
zpoller_destroy (&self->poller);
zsock_destroy(&self->pipe);
free(self);
self = NULL;
}
void
s_account_free (void *argument)
{
account_t *account = (account_t *) argument;
zstr_send (account->actor, "$TERM");
zactor_destroy(&account->actor);
free(account);
zsys_debug("Item removed!");
}
int main(){
zhash_t *table = zhash_new();
int i = 0;
account_t *ptrs[1024];
char key[10];
for(i=0; i<1024; i++){
ptrs[i] = (account_t *) zmalloc (sizeof (account_t));
ptrs[i]->actor = zactor_new (actor_fcn, NULL);
sprintf(&key[0],"%d",i);
zhash_insert(table, key, (void *)ptrs[i]);
zhash_freefn(table, key, s_account_free);
zstr_send (ptrs[i]->actor, "START");
zsock_wait (ptrs[i]->actor);
zsys_debug("%d actor started!",i);
}
i = zhash_size(table);
// Delete all
while(i--){
sprintf(&key[0],"%d",i);
zhash_delete(table, key);
free(ptrs[i]);
}
return 0;
}
#包括
#包括
类型定义结构{
zsock_t*pipe;//Actor命令管道
zpoller\u t*poller;//套接字轮询器
int终止;
}会计人员;
类型定义结构{
zactor_t*演员;
int foo;
}账户;
会计人员*
accountactor_new(zsock_t*管道,void*参数)
{
accountactor_t*self=(accountactor_t*)zmaloc(sizeof(accountactor_t));
断言(自我);
自->管道=管道;
self->poller=zpoller\u new(self->pipe,NULL);
自->终止=0;
回归自我;
}
静态空隙
accountactor_recv_api(accountactor_t*self)
{
//一气呵成地获得管道的全部信息
zmsg_t*请求=zmsg_recv(自->管道);
如果(!请求){
return;//中断
}
char*command=zmsg\u popstr(请求);
if(streq(命令,“启动”)){
zsys_调试(“收到启动命令!”);
zsock_信号(自->管道,0);
}否则
if(streq(命令,“停止”)){
zsys_调试(“收到停止命令!”);
zsock_信号(自->管道,0);
}否则
if(streq(命令,“$TERM”)){
zsys_debug(“$TERM命令已收到!”);
//$TERM命令由zactor_destroy()方法发送
自->终止=1;
}否则{
zsys_错误(“无效命令“%s”,命令);
zsock_信号(自->管道,-1);
}
zmsg_销毁(和请求);
如果(命令){
自由(指挥);
}
}
无效的
参与者fcn(zsock_t*管道,无效*参数)
{
accountactor\u t*self=accountactor\u new(管道,参数);
如果(!self)
return;//中断
int rc=0;
//信号参与者已成功启动
zsock_信号(自->管道,0);
当(!self->终止){
zsock_t*其中=(zsock_t*)zpoller_wait(self->poller,-1);
if(which==self->pipe){
accountactor_recv_api(自身);
}
}
如果(zpoller_终止(self->poller)){
zsys_调试(“轮询器中断!”);
}否则
如果(zpoller_过期(self->poller)){
zsys_调试(“轮询器已过期!”);
}
//自由物体本身
zpoller_销毁(&self->poller);
zsock_销毁(&self->pipe);
自由(自我);
self=NULL;
}
无效的
s_账户自由(无效*参数)
{
account_t*account=(account_t*)参数;
zstr_发送(账户->参与者,“$TERM”);
zactor_销毁(&account->actor);
免费(账户);
zsys_调试(“项目已删除!”);
}
int main(){
zhash_t*表=zhash_new();
int i=0;
账户_t*ptr[1024];
字符键[10];
for(i=0;iactor=zactor\u new(actor\u fcn,NULL);
sprintf(键[0],“%d”,i);
zhash_插入(表,键,(空*)ptrs[i]);
zhash_freefn(表、键、s_账户_free);
zstr_send(ptrs[i]>actor,“START”);
zsock_wait(ptrs[i]->actor);
zsys_调试(“%d个参与者已启动!”,i);
}
i=zhash_尺寸(表);
//全部删除
而(我--){
sprintf(键[0],“%d”,i);
zhash_删除(表、键);
免费(ptrs[i]);
}
返回0;
}
有什么想法吗?我不明白为什么我会达到60个数字的限制。你使用的是什么操作系统?是OS/X吗 当前的actor实现仍然使用pairsocket,它们在内部使用实际的文件句柄来发送信号。每个actor有两个pairsocket,每个pairsocket使用两个文件句柄,因此60个actors=240个文件句柄 在OS/X上,每个进程的默认限制为256。您可以提高此限制,请参阅: 在Linux上,默认值是1024,您可以提高该值。在Windows上,您需要重新编译libzmq,并将FD_SETSIZE设置为16K或类似的值(这是libzmq master现在所做的,但旧版本的值较低) 完全分开:
- 您不需要在构造时进行任何握手,因为zactor_new()已经完成了这项工作,您将看到所有参与者在初始化后都会发送一个信号
- 除非您实际测试系统限制,否则创建1024个参与者可能是多余的。参与者使用系统线程;为了获得最佳性能,您希望每个代码有一个线程。为了获得最佳设计,每个并发工作线程有一个线程