前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >使用CAS实现无锁列队-链表

使用CAS实现无锁列队-链表

作者头像
发布2018-10-09 11:22:50
1.3K0
发布2018-10-09 11:22:50
举报
文章被收录于专栏:
代码语言:javascript
复制
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <iostream>
#include <sys/time.h>
#include <pthread.h>

using namespace std;

#define MAXLEN 200000

#define NUM_THREADS 8

#define CAS __sync_bool_compare_and_swap
#define FAA __sync_fetch_and_add
#define FAS __sync_fetch_and_sub
#define VCAS __sync_val_compare_and_swap

struct node{
    int num;
    node * next;
    node(int i, node* n) :
        num(i), next(n)
    {}
};


struct list{
    node *head;
    node *tail;
    pthread_mutex_t  lock;
    int count;
};

void init(list *plist)
{
    node *tmp = new node(0, NULL);
    plist->head = tmp;
    plist->tail = tmp;
    plist->count = 0;
    pthread_mutex_init(&(plist->lock), NULL);
}



int enque_lock(list *plist, int num)
{
    node *tmp = new node(num, NULL);
    pthread_mutex_lock(&(plist->lock));

    plist->tail->next = tmp;
    plist->tail = tmp;
    plist->count++;
    pthread_mutex_unlock(&(plist->lock));
    return 0;
}
int enque(list *plist, int num)
{
    node *p = NULL;
    node *tmp = new node(num, NULL);
    do
    {
        p = plist->tail;
    } while (CAS(&(p->next), NULL, tmp) == false);
    CAS(&(plist->tail), p, tmp);

    FAA(&(plist->count), 1);
    return 0;
}


void  deque(list *plist)
{
    node *tmp = NULL;
    do{
        tmp = plist->head;
        if (plist->head == plist->tail)
        {
            printf("err\n");
            return;
        }
    } while (CAS(&(plist->head), tmp, tmp->next) == false);
    FAS(&(plist->count), 1);
    delete tmp;
    return;
}

void *SendMsg(void* p)
{
    struct timeval tv_begin, tv_end;
    gettimeofday(&tv_begin, NULL);
    int i = 0;
    while (i++ < MAXLEN)
    {
        enque((list*)p, i);
    }
    gettimeofday(&tv_end, NULL);
    long timeinterval = (tv_end.tv_sec - tv_begin.tv_sec) * 1000000 + (tv_end.tv_usec - tv_begin.tv_usec);
    printf("cost %llu us\n", timeinterval);
}


void *SendMsg2(void* p)
{
    struct timeval tv_begin, tv_end;
    gettimeofday(&tv_begin, NULL);
    int i = 0;
    while (i++ < MAXLEN)
    {
        enque_lock((list*)p, i);
    }
    gettimeofday(&tv_end, NULL);
    long timeinterval = (tv_end.tv_sec - tv_begin.tv_sec) * 1000000 + (tv_end.tv_usec - tv_begin.tv_usec);
    printf("cost %llu us\n", timeinterval);
}



int main(void)
{
    int rc, i;
    pthread_t thread[NUM_THREADS];
    list  ll;
    init(&ll);
    for (i = 0; i < NUM_THREADS; i++)
    {
        printf("Creating thread %i\n", i);
        rc = pthread_create(&thread[i], NULL, SendMsg, (void*)&ll);
        if (rc)
        {
            printf("ERROR; return code is %d\n", rc);
            return -1;
        }
    }

    for (i = 0; i < NUM_THREADS; i++)
    {
        pthread_join(thread[i], NULL);
    }

    while (ll.count > 0)
    {
        deque(&ll);
    }


    for (i = 0; i < NUM_THREADS; i++)
    {
        printf("Creating thread %i\n", i);
        rc = pthread_create(&thread[i], NULL, SendMsg2, (void*)&ll);
        if (rc)
        {
            printf("ERROR; return code is %d\n", rc);
            return -1;
        }
    }

    for (i = 0; i < NUM_THREADS; i++)
    {
        pthread_join(thread[i], NULL);
    }
    return 0;
}

  测试结果如下: 

Creating thread 0 Creating thread 1 Creating thread 2 Creating thread 3 Creating thread 4 Creating thread 5 Creating thread 6 Creating thread 7 cost 227839 us cost 228055 us cost 228034 us cost 228179 us cost 228274 us cost 228328 us cost 228413 us cost 228433 us Creating thread 0 Creating thread 1 Creating thread 2 Creating thread 3 Creating thread 4 Creating thread 5 Creating thread 6 Creating thread 7 cost 486283 us cost 487499 us cost 488358 us cost 488677 us cost 489118 us cost 489658 us cost 489657 us cost 489735 us

加锁版 耗时 比无锁版耗时多一倍

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-09-29 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档