Implementieren threadsicherer Warteschlangen

Ich habe zuvor in Python die Multithreading-Bibliothek verwendet, aber dies ist das erste Mal, dass ich das Threading in C versuche. Ich möchte einen Pool von Arbeitern erstellen. Im Gegenzug sollten diese Mitarbeiter in die Warteschlange pushen oder aus dieser herausspringen. Der folgende Code ist noch nicht ganz da, aber ich habe dies bisher getan:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#define NUMTHREADS 20 /* number of threads to create */

typedef struct node node;
typedef struct queue queue;

struct node {
    char *name;
    node *next;
};

struct queue {
    node *head;
    node *tail;
};

/* pop: remove and return first name from a queue */
char *pop(queue *q)
{
    if (q->head == NULL)
        return NULL;
    char *name = q->head->name;
    node *tmp = q->head;
    q->head = q->head->next;
    free(tmp);
    return name;
}

/* push: add name to the end of the queue */
int push(queue *q, char *name)
{
    node *new = malloc(sizeof(node));
    if (new == NULL)
        return -1;
    new->name = name;
    new->next = NULL;
    if (q->tail != NULL)
        q->tail->next = new;

    q->tail = new;
    if (q->head == NULL) /* first value */
        q->head = new;
    return 0;
}

/* printname: get a name from the queue, and print it. */
void *printname(void *sharedQ)
{
    queue *q = (queue *) sharedQ;
    char *name = pop(q);
    if (name == NULL)
        pthread_exit(NULL);
    printf("%s\n",name);
    pthread_exit(NULL);
}

int main()
{
    size_t i;
    int rc;
    pthread_t threads[NUMTHREADS];
    char *names[] = {
        "yasar",
        "arabaci",
        "osman",
        "ahmet",
        "mehmet",
        "zeliha"
    };

    queue *q = malloc(sizeof(queue));
    q->head = NULL;
    q->tail = NULL;

    /* number of elements in the array */
    size_t numelems = sizeof(names) / sizeof(char *);

    for (i = 0; i < numelems; i++) /* push each name */
        push(q, names[i]);

    for (i = 0; i < NUMTHREADS; i++) { /* fire up threads */
        rc = pthread_create(&threads[i], NULL, printname,
                (void *)q);
        if (rc) {
            printf("Error, return code from pthread is %d\n", rc);
            exit(-1);
        }
    }

    pthread_exit(NULL);
}

Ich habe den obigen Code ausprobiert und er gab jeden Namen immer genau einmal aus. Es wurden keine Namen übersprungen oder derselbe Name zweimal gedruckt. Andererseits bin ich mir nicht sicher, wie threadsicher diese Warteschlangenimplementierung ist. Meine Frage ist also: Ist das eine threadsichere Warteschlange? Wenn nein, warum nicht? Und wie macht man es threadsicher?

Antworten auf die Frage(2)

Ihre Antwort auf die Frage