美文网首页
cas的一个简单测试

cas的一个简单测试

作者: Teech | 来源:发表于2019-07-25 15:05 被阅读0次
    #include<pthread.h>
    #include<stdlib.h>
    #include<unistd.h>
    #include<stdio.h>
    #include <errno.h>
    #include <time.h>
    
    #define   THREAD_NUM 5
    static int count;
    
    struct node {
        struct node* next;
    };
    
    struct node* nodeHead = NULL;
    
    //thread unsafe push
    void pushUnSafe(struct node* new){
        struct node* old = nodeHead;
        new->next = old;
        nodeHead = new;
    }
    
    //thread safe push
    void pushSafe(struct node* newHead){
        for(;;){
            struct node* oldHead = nodeHead;
            newHead->next = oldHead;
            //比较nodeHead和oldHead是否相同 如果相同 返回oldHead,然后把newHead写入nodeHead
            if(__sync_val_compare_and_swap(&nodeHead,oldHead,newHead)==oldHead)
                break;
        }
    }
    
    void* listWorker(void*arg){
        int i= 100;
        struct node *n = (struct node *)arg; 
        while(i--){
            pushSafe( n+i );
        }
        return NULL;
    }
    
    
    int getChilds(struct node* n){
        int count = 0;
        while(n){
            n = n->next;
            count++;
        }
        return count;
    }
    
    
    int testFun()
    {
        pthread_t* pthreads = calloc(THREAD_NUM,sizeof(pthread_t));
        struct node* pNodes = calloc(THREAD_NUM*100,sizeof(struct node));
        for(int i=0;i<THREAD_NUM;i++){
            if(pthread_create(pthreads+i,NULL,listWorker,(void*)(pNodes+i*100))<0){
                    fprintf(stderr,"pthread_create = %d\n",errno);
            }
        }
        void* exitStatus;
        int ret;
        for(int i=0;i<THREAD_NUM;i++){
            if(ret = pthread_join(pthreads[i],&exitStatus) < 0 ){
                fprintf(stderr,"pthread_join = %d\n",errno);
            }
        }
        count = getChilds(nodeHead);
        fprintf(stdout,"count = %d\n",count);
        free(pNodes);
        free(pthreads);
        return 0;
    }
    int main(){
        while(1){
            count = 0;
            nodeHead = NULL;
            sleep(0.1);
            testFun();
            if(count != 500)
                break;
        }
        return 0;
    }
    

    本地测试中如果使用pushUnSafe执行函数运行后会发现大部分时候会运行次数小于500就退出了,节点被覆盖了。

    相关文章

      网友评论

          本文标题:cas的一个简单测试

          本文链接:https://www.haomeiwen.com/subject/rdehrctx.html