#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
加锁版 耗时 比无锁版耗时多一倍