linux多线程之自旋锁


基本概念:

何谓自旋锁?它是为实现保护共享资源而提出一种锁机制。其实,自旋锁与互斥锁比较类似,它们都是为了解决对某项资源的互斥使用。无论是互斥锁,还是自旋锁,在任何时刻,最多只能有一个保持者,也就说,在任何时刻最多只能有一个执行单元获得锁。但是两者在调度机制上略有不同。对于互斥锁,如果资源已经被占用,资源申请者只能进入睡眠状态。但是自旋锁不会引起调用者睡眠,如果自旋锁已经被别的执行单元保持,调用者就一直循环在那里看是否该自旋锁的保持者已经释放了锁,"自旋"一词就是因此而得名。


一、初始化和销毁锁

PTHREAD_SPIN_DESTROY(P)    POSIX Programmer's Manual   PTHREAD_SPIN_DESTROY(P)

NAME
       pthread_spin_destroy,  pthread_spin_init - destroy or initialize a spin
       lock object (ADVANCED REALTIME THREADS)

SYNOPSIS
       #include <pthread.h>

       int pthread_spin_destroy(pthread_spinlock_t *lock);
       int pthread_spin_init(pthread_spinlock_t *lock, int pshared);
两个函数的返回值:若成功,返回0;否则,返回错误编号
关于pthread_spin_init函数的参数pshard,单进程可以设置成PTHREAD_PROCESS_SHARED


二、加锁与解锁

PTHREAD_SPIN_LOCK(P)       POSIX Programmer's Manual      PTHREAD_SPIN_LOCK(P)

NAME
       pthread_spin_lock,  pthread_spin_trylock  -  lock  a  spin  lock object
       (ADVANCED REALTIME THREADS)

SYNOPSIS
       #include <pthread.h>

       int pthread_spin_lock(pthread_spinlock_t *lock);
       int pthread_spin_trylock(pthread_spinlock_t *lock);
       int pthread_spin_unlock(pthread_spinlock_t *lock);
两个函数的返回值:若成功,返回0;否则,返回错误编号

例子1,互斥锁的耗时, gcc pthread_mutex.c -pthread -o mutex:

#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/timeb.h>

static int num = 0;
static int count = 10000000;
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

void Perror(const char *s)
{
    perror(s);
    exit(EXIT_FAILURE);
}

long long getSystemTime() {
    struct timeb t;
    ftime(&t);
    return 1000 * t.time + t.millitm;
}

void* fun2(void *arg)
{
    pthread_t thread_id = pthread_self();
    printf("the thread2 id is %ld\n", (long)thread_id);
    int i = 1;
    for (; i<=count; ++i) {
        pthread_mutex_lock(&mutex);
        num += 1;
        pthread_mutex_unlock(&mutex);
    }
}

int main()
{
    int err;
    pthread_t thread1;
    pthread_t thread2;

    thread1 = pthread_self();
    printf("the thread1 id is %ld\n", (long)thread1);

    long long start = getSystemTime();

    // Create thread
    err = pthread_create(&thread2, NULL, fun2, NULL);
    if (err != 0) {
        Perror("can't create thread2\n");
    }

    int i = 1;
    for (; i<=count; ++i) {
        pthread_mutex_lock(&mutex);
        num += 1;
        pthread_mutex_unlock(&mutex);
    }

    pthread_join(thread2, NULL);
    long long end = getSystemTime();

    printf("The num is %d, pay %lld ms\n", num, (end-start));

    return 0;
}

例子2,自旋锁的耗时,gcc pthread_spin.c -pthread -o spin:

#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/timeb.h>

static int num = 0;
static int count = 10000000;
static pthread_spinlock_t spin;

void Perror(const char *s)
{
    perror(s);
    exit(EXIT_FAILURE);
}

long long getSystemTime() {
    struct timeb t;
    ftime(&t);
    return 1000 * t.time + t.millitm;
}

void* fun2(void *arg)
{
    pthread_t thread_id = pthread_self();
    printf("the thread2 id is %ld\n", (long)thread_id);
    int i = 1;
    for (; i<=count; ++i) {
        pthread_spin_lock(&spin);
        num += 1;
        pthread_spin_unlock(&spin);
    }
}

int main()
{
    int err;
    pthread_t thread1;
    pthread_t thread2;

    pthread_spin_init(&spin, PTHREAD_PROCESS_PRIVATE);

    thread1 = pthread_self();
    printf("the thread1 id is %ld\n", (long)thread1);

    long long start = getSystemTime();

    // Create thread
    err = pthread_create(&thread2, NULL, fun2, NULL);
    if (err != 0) {
        Perror("can't create thread2\n");
    }

    int i = 1;
    for (; i<=count; ++i) {
        pthread_spin_lock(&spin);
        num += 1;
        pthread_spin_unlock(&spin);
    }

    pthread_join(thread2, NULL);
    long long end = getSystemTime();

    printf("The num is %d, pay %lld ms\n", num, (end-start));
    pthread_spin_destroy(&spin);
    return 0;
}

运行结果,可以看到某些条件下,自旋锁是比较快的:



参考:《unix环境高级编程》·第三版


End;



  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值