0

I am expecting to get 100,000 requests at least 100 of them would be concurrent. Each time I get a request, I am creating a new thread and destroy it once it's done using pthread_exit(). Using pthread_detach I am getting 99% success rate. Is there a better way than this?

pthread_t hilo;
// infinite loop
while ((client_sock = accept(server_sock, (struct sockaddr *) &client_sockaddr, &len))) {
    struct ClientSocket socks;
    // some code...
    pthread_create(&hilo, NULL, func, &socks);
    pthread_detach(hilo);
    printf("\nSocket is listening for the next request...\n");
}

I heard pthread_join would be a better way to utilize resources without reaching the thread limit, but the way I am doing it is not concurrent.

pthread_t hilo;    
// infinite loop
while ((client_sock = accept(server_sock, (struct sockaddr *) &client_sockaddr, &len))) {
    struct ClientSocket socks;
    // some code...
    pthread_create(&hilo, NULL, func, &socks);
    pthread_join(hilo, NULL); // it stops the main thread
    printf("\nSocket is listening for the next request...\n");
}

Any ideas would be appreciated!

Hafiz Temuri
  • 3,882
  • 6
  • 41
  • 66
  • Here's a good article to read: http://www.kegel.com/c10k.html – Jeremy Friesner Dec 03 '17 at 05:32
  • 3
    Creating and destroying threads is a very heavy operation. Have you considered using thread pools? – Dave S Dec 03 '17 at 05:37
  • 1
    'I heard pthread_join would be a better way...' no, almost never is pthread_join a better way of doing anything:( – Martin James Dec 03 '17 at 05:46
  • 'I am creating a new thread and destroy it once it's done' - that too, is rarely a good way of doing anything. Queue off the socket etc. to a pool of, say, 150 threads, as suggested by @DaveS – Martin James Dec 03 '17 at 05:49
  • @DaveS, yes, actually that was my first approach. But I couldn't figure out how would I signal back upon the completion of the tasks without stopping/interfering the main thread infinite while loop. Any chance that you can give an example code in C? – Hafiz Temuri Dec 03 '17 at 05:54
  • @HafizTemuri why would you need to signal anything back? Good threads are autonomous threads:) – Martin James Dec 03 '17 at 06:14
  • 1
    'example code' there are plenty examples of producer-consumer queues around, using condvars or semaphores. All you really need to queue up is the server<>client socket as returned from the accept() call. – Martin James Dec 03 '17 at 06:20
  • "*`pthread_detach(hilo);`*": You could create a thread already being detached by passing to `pthread_create()` an attribute set accordingly. – alk Dec 03 '17 at 10:14

1 Answers1

2

Each time I get a request, I am creating a new thread and destroy it once it's done

Don't: it's not a smart thing to do, because thread creation is a heavy-weight operation.

I heard pthread_join would be a better way to utilize resources without reaching the thread limit, but the way I am doing it is not concurrent.

Correct. Whenever you see someone doing pthread_create immediately followed by pthread_join, you can tell that they have no idea what they are doing. The exact same result could be achieved (much more efficiently) by simply calling func directly.

Any ideas would be appreciated!

You need a producer-consumer queue. The listening thread will accept connections and enqueue them for other threads in a (size-limited) thread pool. The other threads will dequeue one item of work, and perform func on that item. Then go back for next item, and so on.

Here is an example producer/consumer implementation. But you can find many others with "producer consumer queue" search.

Employed Russian
  • 199,314
  • 34
  • 295
  • 362