c - 为什么添加线程会使这个简单的套接字服务器更快?

标签 c performance sockets pthreads

这是我的服务器代码:

#include <stdio.h>
#include <arpa/inet.h>
#include <errno.h>
#include <sys/socket.h>
#include <pthread.h>

#define MY_PORT     843
#define MAXBUF      1028
#define NUM_THREADS     2

int pipes[1][2];
int sockfd;

const char *policy =
"<?xml version=\"1.0\"?>\n"
"<!DOCTYPE cross-domain-policy SYSTEM \"/xml/dtds/cross-domain-policy.dtd\">\n"
"<cross-domain-policy>\n"
"<site-control permitted-cross-domain-policies=\"master-only\"/>\n"
"<allow-access-from domain=\"*\" to-ports=\"*\" />\n</cross-domain-policy>\r\n";

void *SendPolicy(void *threadid) {
   int ok, clientfd;
   long tid;
   char buffer[MAXBUF];
   tid = (long) threadid;
   while(1) {
    /* --- Wait for, and recieve a client ---- */
    read(pipes[tid][0], &clientfd, sizeof(int), 0);

    /* --- Recieve --- */
    recv(clientfd, buffer, 128, 0);

    /* --- Send --- */
    send(clientfd, &policy, 250, 0);

    /* --- Close ---*/
    close(clientfd);
   }
}

int main(int argc, char *argv[]) {
    /* --- Create worker threads --- */
    pthread_t threads[NUM_THREADS];
    int t;
    for(t=0; t<NUM_THREADS; t++) {
        pipe(pipes[t]); // <- Create pipes for sending clients
        pthread_create(&threads[t], NULL, SendPolicy, (void *)t);
    }

    /* --- Create streaming socket --- */
    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)  {
    perror("Socket");
    return 1;
    }

    /* --- Initialize address/port structure --- */
    struct sockaddr_in self;
    self.sin_family = AF_INET;
    self.sin_port = htons(MY_PORT);
    self.sin_addr.s_addr = INADDR_ANY;
    self.sin_family = AF_INET;

    /* --- Assign a port number to the socket --- */
    if (bind(sockfd, (struct sockaddr*) &self, sizeof(self)) != 0 ) {
    perror("Error: socket bind");
    return 1;
    }

    /* --- Make it a "listening socket" --- */
    if ( listen(sockfd, 20) != 0 )    {
    perror("socket--listen");
    return 1;
    }

    struct sockaddr_in client_addr;
    int addrlen=sizeof(client_addr);
    int clientfd;
    int current_thread = 0;
    while (1) {
        /* --- Accept a client --- */
    clientfd = accept(sockfd, (struct sockaddr*)&client_addr, &addrlen);

    /* --- Send the client to a worker thread --- */
    write(pipes[current_thread][1], &clientfd, sizeof(int), 0);

    /* --- Cycle the threads --- */
    current_thread++;
    if (current_thread == NUM_THREADS)
        current_thread = 0;
    }

    /* --- Clean up --- */
    close(sockfd);
    pthread_exit(NULL);
    return 0;
}

最初,我编写此计划时使用 5 个线程,但我发现仅使用一个线程即可获得最大 yield 。比没有线程要好得多:

Concurrency Level:      1000
Time taken for tests:   12.607 seconds
Complete requests:      10000
Failed requests:        0
Write errors:           0
Total transferred:      2500000 bytes
HTML transferred:       0 bytes
Requests per second:    793.23 [#/sec] (mean)
Time per request:       1260.672 [ms] (mean)
Time per request:       1.261 [ms] (mean, across all concurrent requests)
Transfer rate:          193.66 [Kbytes/sec] received

这让我很困惑,我不明白为什么只有 1 个线程可以比没有线程或 2、3、4、5 个线程等更快。

最佳答案

主线程也是一个线程,所以即使你只调用一次pthread_create,实际上你也有2个线程,主线程和你创建的线程,因此“1个线程”之间的区别并且没有线程。

对于2个以上线程,你必须考虑拥有多个线程的开销,线程之间的切换通常比进程之间的切换便宜,但不是零。

关于c - 为什么添加线程会使这个简单的套接字服务器更快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15792163/

相关文章:

linux - 如何在shell脚本中创建套接字(域套接字)?

c - 使用 Assembly 在 C 中添加

c - 为什么我的程序的输出包含额外的换行符?

java - Java的DatagramChannel.write()的含义

javascript - JS Websocket 停留在连接到 TCPListener 的状态 - VB.net

multithreading - 在Mac OS X上与EnterCriticalSection最佳等效?

c - 收到错误 : Bad file descriptor: ***stack smashing detected*** at writing in client socket, 但套接字描述符正确

c - 如何在 C 中使用 mod 2 加法制作 XOR?

android - 优化/组合相关的Android布局

mysql - 加快 MySQL 中的 View 速度