1. 程式人生 > >Linux高效能網路:協程系列03-協程的案例

Linux高效能網路:協程系列03-協程的案例

目錄

3.協程的案例

  問題:協程如何使用?與執行緒使用有何區別?

  在做網路IO程式設計的時候,有一個非常理想的情況,就是每次accept返回的時候,就為新來的客戶端分配一個執行緒,這樣一個客戶端對應一個執行緒。就不會有多個執行緒共用一個sockfd。每請求每執行緒的方式,並且程式碼邏輯非常易讀。但是這只是理想,執行緒建立代價,排程代價就呵呵了。
先來看一下每請求每執行緒的程式碼如下:

while (1) {
    int nfds = epoll_wait(epoll_fd, events, curfds, -1);
    if (nfds == -1) {
        perror("epoll_wait");
        break;
    }

    for (i = 0;i < nfds;i ++) {
        int sockfd = listenfd(events[i].data.fd, sockfds);
        if (sockfd) {
            socklen_t len = sizeof(struct sockaddr_in);
            int clientfd = accept(sockfd, (struct sockaddr*)&remote, &len);

            pthread_t thread_id;
            pthread_create(&thread_id, NULL, client_cb, &clientfd);
        }
        else
        {
            ...
        }
}

  這樣的做法,寫完放到生產環境下面,如果你的老闆不打死你,你來找我。我來幫你老闆,為民除害。
  如果我們有協程,我們就可以這樣實現。參考程式碼如下:
  https://github.com/wangbojing/NtyCo/blob/master/nty_server_test.c

while (1) {
    int nfds = epoll_wait(epoll_fd, events, curfds, -1);
    if (nfds == -1) {
        perror("epoll_wait");
        break;
    }

    for (i = 0;i < nfds;i ++) {
        int sockfd = listenfd(events[i].data.fd, sockfds);
        if (sockfd) {
            socklen_t len = sizeof(struct sockaddr_in);
            int clientfd = accept(sockfd, (struct sockaddr*)&remote, &len);

            nty_coroutine *read_co;
            nty_coroutine_create(&read_co, server_reader, &clientfd);
        }
        else
        {
            ...
        }
}

  這樣的程式碼是完全可以放在生成環境下面的。如果你的老闆要打死你,你來找我,我幫你把你老闆打死,為民除害。
  執行緒的API思維來使用協程,函式呼叫的效能來測試協程。
  NtyCo封裝出來了若干介面,一類是協程本身的,二類是posix的非同步封裝
  協程API:

  1. 協程建立
    int nty_coroutine_create(nty_coroutine **new_co, proc_coroutine func, void *arg)  
  2. 協程排程器的執行
    void nty_schedule_run(void)  
  3. POSIX非同步封裝API:
    int nty_socket(int domain, int type, int protocol)
    int nty_accept(int fd, struct sockaddr *addr, socklen_t *len)
    int nty_recv(int fd, void *buf, int length)
    int nty_send(int fd, const void *buf, int length)
    int nty_close(int fd)

    介面格式與POSIX標準的函式定義一致。

更多分享

email: [email protected]
email: [email protected]
email: [email protected]
協程技術交流群:829348971