Skip to content

Instantly share code, notes, and snippets.

@weedge
Last active October 16, 2017 05:30
Show Gist options
  • Save weedge/01d1a9934cbc61726793b80d044ce6ed to your computer and use it in GitHub Desktop.
Save weedge/01d1a9934cbc61726793b80d044ce6ed to your computer and use it in GitHub Desktop.
临界区执行时间长的情况下,spin_lock 执行效率低于 mutex_lock
//Name: spinvsmutex2.c
//http://www.parallellabs.com/2010/01/31/pthreads-programming-spin-lock-vs-mutex-performance-analysis/
//Source: http://www.solarisinternals.com/wiki/index.php/DTrace_Topics_Locks
//Compile(spin lock version): gcc -o spin -DUSE_SPINLOCK spinvsmutex2.c -lpthread
//Compile(mutex version): gcc -o mutex spinvsmutex2.c -lpthread
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <sys/syscall.h>
#define THREAD_NUM 2
pthread_t g_thread[THREAD_NUM];
#ifdef USE_SPINLOCK
pthread_spinlock_t g_spin;
#else
pthread_mutex_t g_mutex;
#endif
__uint64_t g_count;
pid_t gettid()
{
return syscall(SYS_gettid);
}
void *run_amuck(void *arg)
{
int i, j;
printf("Thread %lu started.\n", (unsigned long)gettid());
for (i = 0; i < 1000; i++) {
#ifdef USE_SPINLOCK
pthread_spin_lock(&g_spin);
#else
pthread_mutex_lock(&g_mutex);
#endif
for (j = 0; j < 10000000; j++) {
if (g_count++ == 123456789)
printf("Thread %lu wins!\n", (unsigned long)gettid());
}
#ifdef USE_SPINLOCK
pthread_spin_unlock(&g_spin);
#else
pthread_mutex_unlock(&g_mutex);
#endif
}
printf("Thread %lu finished!\n", (unsigned long)gettid());
return (NULL);
}
int main(int argc, char *argv[])
{
int i, threads = THREAD_NUM;
printf("Creating %d threads...\n", threads);
#ifdef USE_SPINLOCK
pthread_spin_init(&g_spin, 0);
#else
pthread_mutex_init(&g_mutex, NULL);
#endif
for (i = 0; i < threads; i++)
pthread_create(&g_thread[i], NULL, run_amuck, (void *) i);
for (i = 0; i < threads; i++)
pthread_join(g_thread[i], NULL);
printf("Done.\n");
return (0);
}
@weedge
Copy link
Author

weedge commented Oct 12, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment