sumint_single_thread.c
/*************************************************************************
> File Name: sumint.c
> Author: perrynzhou
> Mail: perrynzhou@gmail.com
> Created Time: Sun 04 Mar 2018 02:51:53 AM EST
************************************************************************/
#include <stdio.h>
#include <stdint.h>
#include <pthread.h>
#include <stdlib.h>
typedef struct {
uint64_t data;
int count;
} value;
void add(value* v)
{
for (int i = 0; i < v->count; i++) {
__sync_fetch_and_add(&v->data, 1);
}
}
int main(int argc, char* argv[])
{
int num = atoi(argv[1]);
pthread_t thds[num];
value v = {
.data = 0,
.count = atoi(argv[2])
};
add(&v);
fprintf(stdout, "running %d thread,&value{data=%ld,count=%d}\n", num, v.data, v.count);
return 0;
}
sumint_multi_thread.c
#include <stdio.h>
#include <stdint.h>
#include <pthread.h>
#include <stdlib.h>
typedef struct {
uint64_t data;
int count;
} value;
void add(value* v)
{
for (int i = 0; i < v->count; i++) {
__sync_fetch_and_add(&v->data, 1);
}
}
int main(int argc, char* argv[])
{
int num = atoi(argv[1]);
pthread_t thds[num];
value v = {
.data = 0,
.count = atoi(argv[2])
};
for (int i = 0; i < num; i++) {
pthread_create(&thds[i], NULL, (void*)&add, (void*)&v);
}
for (int i = 0; i < num; i++) {
pthread_join(thds[i], NULL);
}
fprintf(stdout, "running %d thread,&value{data=%ld,count=%d}\n", num, v.data, v.count);
return 0;
}
sumint.go
package main
import (
"flag"
"fmt"
"sync"
"sync/atomic"
)
func main() {
count := flag.Int64("count", 10000, "count")
thread := flag.Int("thread", 1, "thread")
flag.Parse()
var data uint64
var wg sync.WaitGroup
wg.Add(*thread)
for i := 0; i < *thread; i++ {
go func(d *uint64, wg *sync.WaitGroup) {
var i int64
defer wg.Done()
for i = 0; i < *count; i++ {
atomic.AddUint64(d, 1)
}
}(&data, &wg)
}
wg.Wait()
fmt.Printf("running %d goroutine ,&Value{data=%v,count=%v}\n", *thread, data, *count)
}
test.sh
$ cat test.sh
#!/bin/bash
echo "-----c_sumint_single_test-----"
time ./c_sumint_single_test 1 20000000
echo "-----c_sumint_multi_test----"
time ./c_sumint_multi_test 20 1000000
echo "-----go_sumint_nulti_test----"
time ./go_sumint_test -thread=20 -count=1000000
性能测试结果
总结
1.linux 下pthread的性能开销确实比golang 的goroutine开销大,毕竟goroutine是running在pthread之上的,是在线程上实现的多并发,上下文切换远比线程切换小。
2.linux下单线程的性能远比多个goroutine的性能好,少了很多的性能开销。
3.在不同的场景下使用不同的programming tools解决不同的问题。