Skip to content

Instantly share code, notes, and snippets.

@SirLouen
Created October 30, 2024 16:51
Show Gist options
  • Select an option

  • Save SirLouen/1f8ca0b111c76ffdcab3e0af73bfa84d to your computer and use it in GitHub Desktop.

Select an option

Save SirLouen/1f8ca0b111c76ffdcab3e0af73bfa84d to your computer and use it in GitHub Desktop.
Async Pthreads Test for C
#define _DEFAULT_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <curl/curl.h>
#include <pthread.h>
#include <unistd.h>
#include <time.h>
struct MemoryStruct {
char *memory;
size_t size;
int call_id;
};
static size_t WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp) {
size_t realsize = size * nmemb;
struct MemoryStruct *mem = (struct MemoryStruct *)userp;
char *ptr = realloc(mem->memory, mem->size + realsize + 1);
if (!ptr) return 0;
mem->memory = ptr;
memcpy(&(mem->memory[mem->size]), contents, realsize);
mem->size += realsize;
mem->memory[mem->size] = 0;
return realsize;
}
void *api_call(void *arg) {
struct MemoryStruct chunk;
chunk.memory = malloc(1);
chunk.size = 0;
chunk.call_id = *((int*)arg);
free(arg);
CURL *curl = curl_easy_init();
if (curl) {
curl_easy_setopt(curl, CURLOPT_URL, "https://pokeapi.co/api/v2/pokemon/ditto");
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);
printf("API Call #%d initiated [%ld]\n", chunk.call_id, time(NULL));
CURLcode res = curl_easy_perform(curl);
if (res == CURLE_OK) {
char *weight_str = strstr(chunk.memory, "\"weight\":");
if (weight_str) {
int weight;
sscanf(weight_str, "\"weight\": %d", &weight);
printf("API Call #%d result - Ditto's weight: %d [%ld]\n",
chunk.call_id, weight, time(NULL));
}
}
curl_easy_cleanup(curl);
free(chunk.memory);
}
return NULL;
}
int main() {
curl_global_init(CURL_GLOBAL_ALL);
pthread_t api_thread;
time_t start_time = time(NULL);
time_t current_time;
int api_call_made = 0;
int load_id = 1;
int api_call_id = 1;
int expected_iterations;
printf("Starting execution at: [%ld]\n", start_time);
while ((current_time = time(NULL)) - start_time < 2) {
printf("Load #%d [%ld]\n", load_id++, current_time);
expected_iterations = ((current_time - start_time) * 100) + 1;
if ((current_time - start_time) == 1 && !api_call_made) {
int *id = malloc(sizeof(int));
*id = api_call_id++;
pthread_create(&api_thread, NULL, api_call, id);
api_call_made = 1;
}
// Simple compensation mechanism to increase total load
if (load_id < expected_iterations) {
usleep(5000);
} else {
usleep(10000);
}
}
if (api_call_made) {
pthread_join(api_thread, NULL);
}
curl_global_cleanup();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment