> if (pthread_create(&thread_pool[thread_index], 0,
> server_action, &comm_fd) < 0)
You're passing a pointer to a variable which may change it's value before server_action gets a chance to run and inspect the value.

Try
Code:
        if (pthread_create(&thread_pool[thread_index], 0, 
                server_action, (void*)comm_fd) < 0)
with
Code:
void *server_action(void *arg) {
        int comm_fd = (int)arg;

> bzero(str, OUTPUT_BUFFER_SIZE);
> read(comm_fd, str, OUTPUT_BUFFER_SIZE);
There are several things wrong here.
1. You don't pay any attention to the return result of read.
2. If read does actually fill the buffer, you won't have a \0 terminated string that your bzero attempts to solve.

Thread programming is a minefield.
Network programming is another minefield - Fallacies of distributed computing - Wikipedia

Also, there is NO guarantee that if the client sends "hello world" that the server will read "hello world" in a single call to read().
Sure it's fairly guaranteed when you're just on localhost, but if it's a stressed server on the other side of the planet, you might get "he" "l" "l" "o wo" "rld" dribbled to you a few bytes at a time.