Just to add one thing to the answer by @einpoklum and elaborate on the 4th argument void * arg:
Often you might want to add multiple arguments to your callback function (the 3rd argument in the pthread_create function) instead of just one. To do this, you create a struct which includes your arguments and initialize it to the correct values before passing it to the pthread_create function.
To learn more about how to do it, check out this post by @sigjuice or play with the code below:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
struct Node {
struct Node *next_node;
struct Node *previous_node;
int value;
};
struct DoublyLinkedList {
struct Node *head;
struct Node *tail;
int size;
};
struct ThreadArguments {
struct DoublyLinkedList *list;
struct Node *node_ascending;
struct Node *node_descending;
};
int IsListEmpty(struct DoublyLinkedList *ptr) {
int bool = 0;
if (ptr->head != NULL) bool = 1;
return bool;
}
void InsertToList(struct DoublyLinkedList *list, int n) {
struct Node *node = malloc(sizeof(struct Node));
node->value = n;
if (list->size == 0) {
list->head = node;
}
node->previous_node = list->tail;
if (list->tail != NULL) list->tail->next_node = node;
list->tail = node;
list->tail->next_node = NULL;
list->size++;
}
void InitDoublyLinkedList(struct DoublyLinkedList *list) {
list->tail = NULL;
list->head = list->tail;
list->size = 0;
}
void InitDoublyLinkedListWithArray(struct DoublyLinkedList *list, int arr[], int arr_length) {
InitDoublyLinkedList(list);
size_t arr_size = arr_length/sizeof(arr[0]);
for (int i = 0; i < arr_size; i++) {
InsertToList(list, arr[i]);
}
}
void PrintList(struct DoublyLinkedList *list) {
struct Node *node = list->head;
while (node != NULL) {
printf("%d\n", node->value);
node = node->next_node;
}
printf("\n");
}
int GetIntSquared(int n) {
return n*n;
}
static void *TransformValueAscending(void *args) {
struct ThreadArguments *arguments = args;
struct Node *node = arguments->list->head;
int ctr = 0;
int limit = arguments->list->size / 2;
while (node != NULL && ctr < limit) {
arguments->node_ascending = node;
node->value = GetIntSquared(node->value);
node = node->next_node;
ctr++;
}
}
static void *TransformValueDescending(void *args) {
struct ThreadArguments *arguments = args;
struct Node *node = arguments->list->tail;
int ctr = 0;
int limit = arguments->list->size / 2 + arguments->list->size % 2;
while (node != NULL && ctr < limit) {
arguments->node_descending = node;
node->value = GetIntSquared(node->value);
node = node->previous_node;
ctr++;
}
}
int main(int argc, char **argv) {
struct DoublyLinkedList list;
int arr[] = {2,3,4,5,6,7,8,9,10,11,12};
InitDoublyLinkedListWithArray(&list, arr, sizeof(arr));
// printf("%d\n", list.head->value);
PrintList(&list);
// create two new threads
pthread_t thread_1;
pthread_t thread_2;
struct ThreadArguments args;
args.list = &list;
args.node_ascending = list.head;
args.node_descending = list.tail;
int error_code_t1 = pthread_create(&thread_1, NULL, TransformValueAscending, (void*)&args);
void *thread_1_return_value;
int error_code_t2 = pthread_create(&thread_1, NULL, TransformValueDescending, (void*)&args);
void *thread_2_return_value;
pthread_join(thread_1, &thread_1_return_value);
pthread_join(thread_2, &thread_2_return_value);
PrintList(&list);
return 0;
}