zoukankan      html  css  js  c++  java
  • 使用CAS实现无锁列队-链表

    #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
    ");
                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 ", 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 ", 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 ", i); rc = pthread_create(&thread[i], NULL, SendMsg, (void*)&ll); if (rc) { printf("ERROR; return code is %d ", 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 ", i); rc = pthread_create(&thread[i], NULL, SendMsg2, (void*)&ll); if (rc) { printf("ERROR; return code is %d ", 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

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

  • 相关阅读:
    ceil函数 floor函数 floor函数 round函数 取整函数
    Havel–Hakimi algorithm(判断度数序列是否可图)
    最小费用最大流
    数论 (大数,小费马定理,欧拉定理,威尔逊定理,快速数论变换(NNT)模版)
    Give Candies(费马小定理)
    Yet Another Crosses Problem
    并查集
    杭电多校第一场-M-Code
    2018ICPC赛后总结
    营业额统计
  • 原文地址:https://www.cnblogs.com/myd620/p/9724679.html
Copyright © 2011-2022 走看看