# Include <stdint. h> # include <assert. h> # include <stdio. h> # include <pthread. h> # include <unistd. h> # define SPIN_LOCK 1 static uint32_t atomic_cmp_set (uint32_t * lock, uint32_t old, uint32_t set) {uint8_t rslt = 0; asm volatile ("lock; "// lock if SMP" cmpxchgl % 3, % 1; "" sete % 0; ":" = a "(rslt):" m "(* lock ), "a" (old), "r" (set): "cc", "memory"); return rslt;} static uint32_t g_continue = 1; static volati Le uint32_t g_count1 = 0; static volatile uint32_t g_count2 = 0; static uint32_t g_lock = 0; static void * thread_func (void * p_param) {while (g_continue (! Atomic_cmp_set (& g_lock, 0, 1) {sched_yield () ;}# endif ++ g_count1; ++ g_count2; # if SPIN_LOCK g_lock = 0; # endif} return NULL ;} int main (int argc, char * argv []) {pthread_t t1 = 0, t2 = 0; pthread_create (& t1, NULL, & thread_func, NULL); pthread_create (& t2, NULL, & thread_func, NULL); sleep (1); g_continue = 0; pthread_join (t1, NULL); pthread_join (t2, NULL); fprintf (stderr, "% u, % u \ n ", g_count1, g_coun T2); return 0 ;} ######################################## ######################################## ######################################## ######################################## ################### add Process Synchronization # include <stdint. h> # include <stdlib. h> # include <stdio. h> # include <assert. h> # include <stdio. h> # include <pthread. h> # include <unistd. h> # include <sys/shm. h> # include <sys/wait. h> # define THREAD 0 # define SP IN_LOCK 1 # if SPIN_LOCKstatic uint32_t atomic_cmp_set (uint32_t * lock, uint32_t old, uint32_t set) {uint8_t rslt = 0; assert (NULL! = Lock); asm volatile ("lock;" // lock if SMP "cmpxchgl % 3, % 1;" "sete % 0;": "= a" (rslt ): "m" (* lock), "a" (old), "r" (set): "cc", "memory"); return rslt ;} # endif # if THREADstatic uint32_t g_continue = 1; # elsestatic void * gp_continue = NULL; # endif # if THREADstatic volatile uint32_t g_count1 = 0; static volatile uint32_t g_count2 = 0; # elsestatic volatile void * gp_count1 = 0; static volatile void * gp_c Ount2 = 0; # endifstatic int shmid = 0; # if SPIN_LOCK # if THREADstatic uint32_t g_lock = 0; # elsestatic void * gp_lock = NULL; # endif # endifstatic void * thread_func (void * p_param) {# if THREAD while (g_continue) {# else while (* (uint32_t *) gp_continue) {# endif # if SPIN_LOCK # if THREAD while (! Atomic_cmp_set (& g_lock, 0, 1) {# else while (! Atomic_cmp_set (uint32_t *) gp_lock, 0, 1) {# endif sched_yield () ;}# endif # if THREAD ++ g_count1; ++ g_count2; # else ++ (* (volatile uint32_t *) gp_count1); ++ (* (volatile uint32_t *) gp_count2); # endif # if SPIN_LOCK # if THREAD g_lock = 0; # else * (uint32_t *) gp_lock = 0; # endif/* THEAD */# endif} # if SPIN_LOCK # if! THREAD shmdt (gp_lock); # endif return NULL;} int main (int argc, char * argv []) {// create shared memory shmid = shmget (IPC_PRIVATE, 4096, IPC_CREAT | 0600); if (-1 = shmid) {return-1 ;}# if THREAD pthread_t t1 = 0, t2 = 0; pthread_create (& t1, NULL, & thread_func, NULL); pthread_create (& t2, NULL, & thread_func, NULL); sleep (1); g_continue = 0; pthread_join (t1, NULL); pthread_join (t2, NULL); # else # if SPIN_LOCK gp_lock = shmat (shmid, 0, 0); * (uint32_t *) gp_lock = 0; # endif gp_continue = (char *) shmat (shmid, 0, 0) + 4; * (uint32_t *) gp_continue = 1; gp_count1 = (char *) shmat (shmid, 0, 0) + 8; * (uint32_t *) gp_count1 = 0; gp_count2 = (char *) shmat (shmid, 0, 0) + 12; * (uint32_t *) gp_count2 = 0; switch (fork () {case 0: break; case-1: exit (-1); default: {int x = fork (); if (x> 0) {sleep (1); * (uint32_t *) gp_continue = 0; wait (NULL); shmdt (gp_continue); (void) shmctl (shmid, IPC_RMID, 0 ); exit (0) ;}} thread_func (NULL); # endif fprintf (stderr, "% u, % u \ n", # if THREAD g_count1, g_count2 ); # else * (volatile uint32_t *) gp_count1, * (volatile uint32_t *) gp_count2); # endif return 0 ;}
PS: The Assembly Code is derived from nginx, And the CAS mechanism can only implement spin locks. Because the user State cannot suspend the wake-up thread, the futex can be used to implement mutex locks.