#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就退出了,节点被覆盖了。
网友评论