Code Monkey home page Code Monkey logo

Comments (6)

zhengshuxin avatar zhengshuxin commented on May 9, 2024

acl 协程底层也是通过 epoll 的事件触发的,上层虽是同步调用,在下层转成异步过程。你是否可以提供一个简单的示例演示一下?

from acl.

jiezinaxumi avatar jiezinaxumi commented on May 9, 2024

使用方式是线程+协程
//主线程accept连接
int main(int argc, char argv[])
{
acl::server_socket server;
if (server.open(sockAddr) == false) {
logger_error("open %s error\r\n", sockAddr);
return exit(1);
}
while (true) {
acl::socket_stream
cstream = server.accept();
if (cstream == NULL) {
logger_error("accept failed: %s", acl::last_serror());
break;
}

    cstream->set_tcp_solinger(true, 10);
    cstream->set_tcp_nodelay(true);
    cstream->set_rw_timeout(0);
    cstream->set_tcp_non_blocking(false);
    unsigned int uiIdx = cstream->sock_handle() % g_CfgVar.uiMaxThreads;
    MPostMsg *ptrMsg = new MPostMsg(sockType, cstream);
    if (acl_mbox_send(g_mbox[uiIdx], ptrMsg) < 0) {
        delete cstream;
        delete ptrMsg;
    }   
}   

}

//启动两个MasterThread线程
void* MasterThread::run(void)
{
acl_fiber_create(fiber_callback, this, g_CfgVar.uiFiberStackSize);
acl_fiber_schedule();
return NULL;
}

//线程入口
void MasterThread::fiber_callback(ACL_FIBER * /* f */, void ctx)
{
MasterThread
me = (MasterThread *)ctx;
me->mutex_ = acl_fiber_mutex_create();
for (;;) {
MPostMsg ptrMsg = (MPostMsg)acl_mbox_read(me->mbox_, 0, NULL);
if (ptrMsg == NULL)
continue;

    switch (ptrMsg->command)
    {
      case CMD_TCP_ID:
      {
        acl::socket_stream *client = (acl::socket_stream *)ptrMsg->ptrParam;
        if (g_CfgVar.uiMaxFibers > me->fibers_cnt_) {
            (new MasterTcpFiber(me, client))->start(g_CfgVar.uiFiberStackSize);
        }
        else {
            logger_error("fiber cnt=%d > max(%d), close client fd=%d", me->fibers_cnt_, g_CfgVar.uiMaxFibers, client->sock_handle());
            client->close();
            delete client;
        }
      }
  break;
  case ...:
  break;
}
delete ptrMsg;
ptrMsg = NULL;
 acl_fiber_mutex_free(me->mutex_);

}

// 协程入口,构造函数日志表示第一个socket在第二个socket之后才收到
MasterTcpFiber::MasterTcpFiber(MasterThread* t, acl::socket_stream* c)
:MFiberBase(t, c)
{
logger("accept fiber here delay...");
socket_stream_ = c;
buffer_ = acl_mymalloc(g_CfgVar.uiMaxReadBuffer);
acl_assert(buffer_ != NULL);
}

// 协程run
void MasterTcpFiber::run(void)
{
int ret = 0;
while(!socket_stream_->eof()){
ret = socket_stream_->read(buffer_, sizeof(NetPkgHeader));
...
}
}

from acl.

zhengshuxin avatar zhengshuxin commented on May 9, 2024

谢谢提供样例,我会研究测试一下。

from acl.

jiezinaxumi avatar jiezinaxumi commented on May 9, 2024
cstream->set_rw_timeout(0);
cstream->set_tcp_non_blocking(false);

阻塞模式设置rw timeout=0,源码中,会直接调用acl_socket_read(),就是 recv,会block住
int acl_socket_read(ACL_SOCKET fd, void *buf, size_t size,
int timeout, ACL_VSTREAM *fp, void *arg acl_unused)
{
#if 0
WSABUF wsaData;
DWORD dwBytes = 0;
DWORD flags = 0;
int ret;

    wsaData.len = (u_long) size;
    wsaData.buf = (char*) buf;
    ret = WSARecv(fd, &wsaData, 1, &dwBytes, &flags, NULL, NULL);
    if (ret == SOCKET_ERROR)
            return -1;
    if (dwBytes == 0)
            return -1;
    return dwBytes;

#else
if (fp != NULL && fp->read_ready)
fp->read_ready = 0;
else if (timeout > 0 && acl_read_wait(fd, timeout) < 0)
return -1;

    return recv(fd, buf, (int) size, 0);

#endif
}
应该是这里引起的,我修改下timeout再看看,谢谢

from acl.

zhengshuxin avatar zhengshuxin commented on May 9, 2024

我写了个类似的例子,没有发现你所说的问题,可参考:
https://github.com/acl-dev/demo/blob/master/thread_fiber_server.cpp
https://github.com/acl-dev/demo/blob/master/thread_fiber_client.cpp

from acl.

jiezinaxumi avatar jiezinaxumi commented on May 9, 2024

很详细的例子,谢谢,block阻塞模式下,设置timeout 2秒后,没有再出现了;后续修改为nonblock会不会致协程切换的频率相比block模式,过于频繁,增加context switch?

from acl.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.