The code is not thread safe.
The push and pop functions are not thread safe. In the code, pressing is only performed by one thread, so it does not matter, but pops are executed by several threads.
1. char *name = q->head->name; 2. node *tmp = q->head; 3. q->head = q->head->next; 4. free(tmp);
Imagine that thread A runs before and including line 2. Then thread B executes and includes line 4. Thread A resumes execution. He found that q-> head is already free () ed.
Now it discusses logical issues.
However, there are physical problems that need to be considered.
Imagine that we had a locking mechanism in which threads could synchronize their behavior, so that only one thread at a time could execute code in lines 1 through 4, for example. a mutex, which is the object of only one thread, can โholdโ at a time, and when an attempt to get a mutex blocks the thread until the current thread is released.
0. get mutex 1. char *name = q->head->name; 2. node *tmp = q->head; 3. q->head = q->head->next; 4. free(tmp); 5. release mutex
We would still have a problem: records executed by any CPU core (not a thread) are immediately visible only to threads on that core; not for threads on other cores.
Simply synchronizing execution is not enough; at the same time, we must also ensure that the entries made by the kernel become visible to other kernels.
(Un), fortunately, all modern synchronization methods also perform this flushing of a record (for example, when you get a mutex, you also clear all records in memory). I say, unfortunately, because you - never need this behavior, and it is bad for performance.