概述
#include
#include
#include
#include
#include
#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 volatile 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) {
#if SPIN_LOCK
while (!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, %un",
g_count1,
g_count2);
return 0;
}
##########################################################################################
##########################################################################################
增加进程同步
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define THREAD 0
#define SPIN_LOCK 1
#if SPIN_LOCK
static 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 THREAD
static uint32_t g_continue = 1;
#else
static void *gp_continue = NULL;
#endif
#if THREAD
static volatile uint32_t g_count1 = 0;
static volatile uint32_t g_count2 = 0;
#else
static volatile void *gp_count1 = 0;
static volatile void *gp_count2 = 0;
#endif
static int shmid = 0;
#if SPIN_LOCK
#if THREAD
static uint32_t g_lock = 0;
#else
static void *gp_lock = NULL;
#endif
#endif
static 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
#endif
return NULL;
}
int main(int argc, char *argv[])
{
// 创建共享内存
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, %un",
#if THREAD
g_count1,
g_count2);
#else
*(volatile uint32_t *)gp_count1,
*(volatile uint32_t *)gp_count2);
#endif
return 0;
}
ps: 汇编代码源自nginx,CAS机制只能实现自旋锁,因为用户态无法挂起唤醒线程,可以借助futex实现互斥锁。
最后
以上就是过时纸鹤为你收集整理的linux 用户态锁实现,Linux下用户态自旋锁的实现的全部内容,希望文章能够帮你解决linux 用户态锁实现,Linux下用户态自旋锁的实现所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复