I'm writing a program that performs some processing on each packet received. I've taken some of the multithreading code and put it into its own program:
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <signal.h>
#include <unistd.h>
struct pktstruct {
//u_char *args; - Not used
const struct pcap_pkthdr *head;
const u_char *packt;
int thread_no;
};
void* packet_handler(void *arguments);
void handler_dispatcher(u_char *args, const struct pcap_pkthdr *header, const u_char *packet);
pthread_t threads[20];
volatile sig_atomic_t thread_done[20];
int main(int argc, char *argv[])
{
for (int i = 0; i < 20; i ++){
thread_done[i] = 0;
}
while (1) {
handler_dispatcher(NULL,NULL,NULL);
}
}
void* packet_handler(void *arguments)
{
struct pktstruct *args = arguments;
printf("Hello %d\n", args->thread_no);
thread_done[args->thread_no] = 1;
return NULL;
}
void handler_dispatcher(u_char *args, const struct pcap_pkthdr *header, const u_char *packet){
struct pktstruct pkt;
pkt.head = header;
pkt.packt = packet;
for (int t = 0; t < 20; t++) {
if ( thread_done[t] ) {
//printf("Thread %d is done! Joining...\n", t);
pthread_join(threads[t], NULL);
thread_done[t] = 0;
}
}
for (int q = 0; q < 20; q++) {
if ( !thread_done[q] ) {
pkt.thread_no = q;
pthread_create(&threads[q], NULL, &packet_handler, &pkt);
break;
}
}
}
Originally I was just spawning a thread for each packet. I'm not very familiar with C so it took me a while to realize stuff like threads don't clean up, return NULL is better than pthread_exit(NULL) etc.
The program prints a bunch of "Hello"s and then stops functioning properly. HTOP shows 256G for VIRT and 266M for RES, but the only reason they stop growing is because the program stops working.
I understand that it would be 'good design' to use mutexes, however I thought that since I'm checking for free slots in each iteration, surely even if I miss a thread just becoming available, next iteration I will know about it.
To be fully honest, I tried using mutexes too -locking and unlocking before and after the 'for' loops in handler_dispatcher, as well as before and after the assignment in packet_handler- but the program again stops working after a brief moment with 256G VIRT and 266M RES.
What is it that I'm doing wrong?
Edit: Added headers. Compile with gcc test.c -o test -Wall -lpthread