Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tck socket stream 的一个问题(协程相关) #80

Closed
wzy2687 opened this issue Mar 10, 2019 · 4 comments
Closed

tck socket stream 的一个问题(协程相关) #80

wzy2687 opened this issue Mar 10, 2019 · 4 comments
Milestone

Comments

@wzy2687
Copy link

wzy2687 commented Mar 10, 2019

代码大概如下:

tb_stream_ref_t stream;
void hand_read(tb_cpointer_t *priv)
{
    int32_t data;
    tb_bool_t s = tb_stream_bread(stream,&data,4);
    while(1)tb_sleep(1);
}
void hand_open(tb_cpointer_t *priv)
{
    stream = tb_stream_init_from_sock("127.0.01", 10000
            , TB_SOCKET_TYPE_TCP, tb_false);
    tb_bool_t rt = tb_stream_open(stream);
    tb_co_scheduler_ref_t scheduler = tb_co_scheduler_self();
    tb_coroutine_start(scheduler,hand_read,tb_null,0);
    while(1)tb_sleep(1);
    return;
}

void main()
{
    tb_co_scheduler_ref_t scheduler = tb_co_scheduler_init();
     tb_coroutine_start(scheduler,hand_open,tb_null,0);
    tb_co_scheduler_loop(scheduler,tb_true);
}

报错

[tbox]: [poller]: [error]: insert socket(0x4) events: 17 failed, errno: 17 at tb_poller_insert(): 246, src/tbox/platform/linux/poller_epoll.c
[tbox]: [scheduler_io]: [error]: failed to insert sock(0x4) to poller on coroutine(0x55716cf8dfc8)! at tb_co_scheduler_io_wait(): 407, src/tbox/coroutine/impl/scheduler_io.c

我跟踪了下, 原因可能是:
针对socket stream (tcp linux):

调用 tb_co_scheduler_io_wait 时候, 会判断当前 coroutine
是否有该socket , 如果已经在epoll 中,就先删除. 如果没有, 就add.
这个时候是不是应该判断 socket fd 是否在epoll 中. (因为当前
协程没有,其它协程可能已经把socke fd放到epoll 中了)

@waruqi
Copy link
Member

waruqi commented Mar 10, 2019

目前不支持一个socket,跨多个协程内进行io读写,只能在一个协程里面操作(我这边一般不这么做,而且为了效率,socket跟协程有cache优化,是n:1绑定的,多个协程来回操作同一个socket会有问题),目前请尽量避免这么做。。

上面的代码有以下问题:

  1. stream不要全局访问,一个协程对应一个stream
  2. void hand_read(tb_cpointer_t *priv)函数声明不对,应给是tb_cpointer_t priv
  3. tb_stream_open 和 tb_co_scheduler_init 的返回值没有判断,也没有对应的close/exit操作
  4. hand_open 和 hand_recv没必要弄成两个协程,一个stream操作对应一个协程进行操作就行了
  5. 没必要加while(1)tb_sleep(1); ,协程执行完,直接return返回就行了,如果非要永久挂起,调用tb_coroutine_suspend就行了,没必要每秒sleep一次

例如:

void hand_stream(tb_cpointer_t priv)
{
    tb_stream_ref_t stream = tb_stream_init_from_sock("127.0.0.1", 9001, TB_SOCKET_TYPE_TCP, tb_false);
    if (tb_stream_open(stream))
    {
        int32_t data;
        tb_bool_t ok = tb_stream_bread(stream, (tb_byte_t*)&data,4);
        tb_stream_close(stream);
    }
}

一个协程就能搞定,为什么要在两个协程内操作呢, 即使处于代码封装目的,直接同一协程内进行函数调用就行了,没必要再开个协程进行read操作,例如

void hand_read(tb_stream_ref_t stream)
{
        int32_t data;
        tb_bool_t ok = tb_stream_bread(stream, (tb_byte_t*)&data,4);
}
void hand_open(tb_cpointer_t priv)
{
    tb_stream_ref_t stream = tb_stream_init_from_sock("127.0.0.1", 9001, TB_SOCKET_TYPE_TCP, tb_false);
    if (tb_stream_open(stream))
    {
        hand_read(stream);
        tb_stream_close(stream);
    }
}

@waruqi
Copy link
Member

waruqi commented Mar 10, 2019

多个协程同时操作socket,我之后会做支持,不过可能需要等上一段时间了。。

@waruqi waruqi added this to the v1.6.4 milestone Mar 10, 2019
@wzy2687
Copy link
Author

wzy2687 commented Mar 11, 2019

收到, 多谢. 期待 v1.6.4

@waruqi
Copy link
Member

waruqi commented Oct 8, 2019

我dev上已经支持了,你可以试试。。

@waruqi waruqi closed this as completed Oct 11, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants