golang channel測速程序:golang
package main import ( "runtime" ) var PC_DATA_SIZE int var chEnd chan int func producer(ch chan byte) { for i := 0; i < PC_DATA_SIZE; i++ { ch <- 0 } chEnd <- 0 } func consumer(ch chan byte) { for i := 0; i < PC_DATA_SIZE; i++ { <-ch } chEnd <- 0 } func main() { runtime.GOMAXPROCS(runtime.NumCPU()) PC_DATA_SIZE = 10000000 chEnd = make(chan int) ch := make(chan byte, 1024) go producer(ch) go consumer(ch) <-chEnd <-chEnd }
C語言有鎖併發隊列:併發
#include <pthread.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> #define PC_DATA_SIZE 10000000 typedef struct Queue{ uint8_t *data; int front; int rear; int size; int maxSize; pthread_mutex_t mutex; pthread_cond_t empty; pthread_cond_t fill; }Queue; Queue *QueueInit(int maxSize){ Queue *queue=malloc(sizeof(Queue)); if(queue==NULL){ perror("malloc"); return NULL; } queue->data=malloc(maxSize); if(queue->data==NULL){ perror("malloc"); free(queue); return NULL; } queue->front=0; queue->rear=0; queue->size=0; queue->maxSize=maxSize; if(pthread_mutex_init(&queue->mutex,NULL)!=0){ perror("pthread_mutex_init"); return NULL; } if(pthread_cond_init(&queue->empty,NULL)!=0){ perror("pthread_cond_init"); return NULL; } if(pthread_cond_init(&queue->fill,NULL)!=0){ perror("pthread_cond_init"); return NULL; } return queue; } int QueueIn(Queue *queue,uint8_t data){ if(pthread_mutex_lock(&queue->mutex)!=0){ perror("pthread_mutex_lock"); return -1; } while(queue->size==queue->maxSize){ if(pthread_cond_wait(&queue->empty,&queue->mutex)!=0){ perror("pthread_cond_wait"); return -1; } } queue->data[queue->front]=data; ++queue->front; queue->front%=queue->maxSize; ++queue->size; if(pthread_cond_signal(&queue->fill)!=0){ perror("pthread_cond_signal"); } if(pthread_mutex_unlock(&queue->mutex)!=0){ perror("pthread_mutex_unlock"); return -1; } return 0; } int QueueOut(Queue *queue,uint8_t *data){ if(pthread_mutex_lock(&queue->mutex)!=0){ perror("pthread_mutex_lock"); return -1; } while(queue->size==0){ if(pthread_cond_wait(&queue->fill,&queue->mutex)!=0){ perror("pthread_cond_wait"); return -1; } } *data=queue->data[queue->rear]; ++queue->rear; queue->rear%=queue->maxSize; --queue->size; if(pthread_cond_signal(&queue->empty)!=0){ perror("pthread_cond_signal"); } if(pthread_mutex_unlock(&queue->mutex)!=0){ perror("pthread_mutex_unlock"); return -1; } return 0; } void QueueDestroy(Queue *queue){ if(pthread_cond_destroy(&queue->fill)!=0){ perror("pthread_cond_destroy"); } if(pthread_cond_destroy(&queue->empty)!=0){ perror("pthread_cond_destroy"); } if(pthread_mutex_destroy(&queue->mutex)!=0){ perror("pthread_mutex_destroy"); } free(queue->data); free(queue); } void *producerStart(void *arg){ Queue *queue=(Queue*)arg; int64_t sum=0; int i; for(i=0;i<PC_DATA_SIZE;++i){ uint8_t data=(uint8_t)i; if(QueueIn(queue,data)<0){ perror("QueueIn"); return NULL; } sum+=data; } printf("producerStart sum %ld\n",sum); return NULL; } void *consumerStart(void *arg){ Queue *queue=(Queue*)arg; int64_t sum=0; int i; for(i=0;i<PC_DATA_SIZE;++i){ uint8_t data; if(QueueOut(queue,&data)<0){ perror("QueueOut"); return NULL; } sum+=data; } printf("consumerStart sum %ld\n",sum); return NULL; } int main(void){ Queue *queue=QueueInit(1024); if(queue==NULL){ perror("QueueInit"); return -1; } pthread_t producerTId; if(pthread_create(&producerTId,NULL,producerStart,queue)!=0){ perror("pthread_create"); return -1; } pthread_t consumerTId; if(pthread_create(&consumerTId,NULL,consumerStart,queue)!=0){ perror("pthread_create"); return -1; } pthread_join(producerTId,NULL); pthread_join(consumerTId,NULL); QueueDestroy(queue); return 0; }
C語言無鎖併發隊列:post
#include <pthread.h> #include <semaphore.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> #define PC_DATA_SIZE 10000000 typedef struct Queue{ uint8_t *data; int front; int rear; int maxSize; sem_t empty; sem_t fill; }Queue; Queue *QueueInit(int maxSize){ Queue *queue=malloc(sizeof(Queue)); if(queue==NULL){ perror("malloc"); return NULL; } queue->data=malloc(maxSize); if(queue->data==NULL){ perror("malloc"); free(queue); return NULL; } queue->front=0; queue->rear=0; queue->maxSize=maxSize; if(sem_init(&queue->empty,0,queue->maxSize)<0){ perror("sem_init"); return NULL; } if(sem_init(&queue->fill,0,0)<0){ perror("sem_init"); return NULL; } return queue; } int QueueIn(Queue *queue,uint8_t data){ if(sem_wait(&queue->empty)<0){ perror("sem_wait"); return -1; } queue->data[queue->front]=data; ++queue->front; queue->front%=queue->maxSize; if(sem_post(&queue->fill)<0){ perror("sem_post"); return -1; } return 0; } int QueueOut(Queue *queue,uint8_t *data){ if(sem_wait(&queue->fill)<0){ perror("sem_wait"); return -1; } *data=queue->data[queue->rear]; ++queue->rear; queue->rear%=queue->maxSize; if(sem_post(&queue->empty)<0){ perror("sem_post"); return -1; } return 0; } void QueueDestroy(Queue *queue){ if(sem_destroy(&queue->empty)<0){ perror("sem_destroy"); } if(sem_destroy(&queue->fill)<0){ perror("sem_destroy"); } free(queue->data); free(queue); } void *producerStart(void *arg){ Queue *queue=(Queue*)arg; int64_t sum=0; int i; for(i=0;i<PC_DATA_SIZE;++i){ uint8_t data=(uint8_t)i; if(QueueIn(queue,data)<0){ perror("QueueIn"); return NULL; } sum+=data; } printf("producerStart sum %ld\n",sum); return NULL; } void *consumerStart(void *arg){ Queue *queue=(Queue*)arg; int64_t sum=0; int i; for(i=0;i<PC_DATA_SIZE;++i){ uint8_t data; if(QueueOut(queue,&data)<0){ perror("QueueOut"); return NULL; } sum+=data; } printf("consumerStart sum %ld\n",sum); return NULL; } int main(void){ Queue *queue=QueueInit(1024); if(queue==NULL){ perror("QueueInit"); return -1; } pthread_t producerTId; if(pthread_create(&producerTId,NULL,producerStart,queue)!=0){ perror("pthread_create"); return -1; } pthread_t consumerTId; if(pthread_create(&consumerTId,NULL,consumerStart,queue)!=0){ perror("pthread_create"); return -1; } pthread_join(producerTId,NULL); pthread_join(consumerTId,NULL); QueueDestroy(queue); return 0; }
TCP:測試
dd if=/dev/zero of=send bs=10000 count=100000 nc -l 0.0.0.0 12345 > recv time nc 127.0.0.1 12345 < send
速度:ui
第一次測試 第二次測試 平均速度 golang 1.322s 1.301s 58.2Mbps C有鎖併發隊列 3.693s 3.619s 20.9Mbps C無鎖併發隊列 2.008s 1.767s 40.4Mbps TCP 2.232s 2.213s 3433.0Mbps
測試暫時完成了,留下了不少問題:code
一、爲何golang的channel比C語言快?若是C語言在內核態實現併發隊列呢?隊列
二、爲何TCP如此之快?it