大约是2010年吧,那个时候我开始写c,没基础。
当时用到了锁,我记得pthread_mutex_lock有的时候要1秒多钟,我当时有没有确定是不是因为有线程锁定了,所以才造成的,就得出结论,pthread_mutex_lock效率极低!
后来我基本能无锁就无锁,但这确实很难,不是任何时候都有办法做到。
我今天又遇到无法无锁的,自己就又写了套数字锁:
/**
* 高低优先级双线程双数字锁,简称双数锁
* 用2个数字实现一个锁,一个具有高优先级、一个具有低优先级
*/
//声明一个
#define DOULE_NUM_LOCK_DECLAR(lock_low_priority, lock_high_priority) int lock_low_priority=0;\
int lock_high_priority=0
#define DOULE_NUM_LOCK_IMPORT(lock_low_priority, lock_high_priority) extern int lock_low_priority;\
extern int lock_high_priority
#define DOULE_NUM_LOCK_LOW_LOCK(lock_low_priority, lock_high_priority) lock_low_priority = 1;\
while(lock_high_priority>0){\
usleep(50);\
}\
\
usleep(100);\
while(lock_high_priority>0){\
usleep(50);\
}
#define DOULE_NUM_LOCK_HIGH_LOCK(lock_low_priority, lock_high_priority) while(lock_low_priority>0){\
usleep(50);\
}\
lock_high_priority = 1
这个东西每秒最多就是1000把次,完全能满足我需求,但是,这看起来并不够快啊。
所以,我怀疑当年的结论。查阅了文档。
最后自己写了个测试pthread_mutex_lock的代码:
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <sys/epoll.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <errno.h>
#include <pthread.h>
#include <math.h>
int flag = 0;
int flag1 = 0;
#define NUM 3
void* _1thred(void* data){
pthread_mutex_t* mute = (pthread_mutex_t* ) data;
flag ++;
struct timeval ts,sts,ets;
while(flag<NUM){//确保3个线程能尽量同时开始,效果并不理想,但基本可用
usleep(1);
}
gettimeofday(&ts, NULL);
int count_s=0, count_ms = 0;
int count = 100000;
while(count--){
gettimeofday(&sts, NULL);
pthread_mutex_lock(mute);
gettimeofday(&ets, NULL);
count_s += ets.tv_sec - sts.tv_sec;
count_ms += ets.tv_usec - sts.tv_usec;
pthread_mutex_unlock(mute);
}
int v = count_s*1000000 + count_ms;
printf("[%u] V=%u,from[%d.%06d] to [%d.%06d]\n", pthread_self(), v, ts.tv_sec, ts.tv_usec, ets.tv_sec, ets.tv_usec);
flag1 ++;
printf("%d/%d\n", flag, flag1);
}
void start_1_thread(pthread_mutex_t* mute){
pthread_t th_sql;
pthread_attr_t attr_sql;
pthread_attr_init(&attr_sql);
pthread_attr_setdetachstate(&attr_sql, PTHREAD_CREATE_DETACHED);
if(pthread_create(&th_sql, &attr_sql, _1thred, mute)!=0)
{
printf(" pthread_create failed login_thread\n");
exit(1);
}
}
void start_2_thread(pthread_mutex_t* mute){
pthread_t th_sql;
pthread_attr_t attr_sql;
pthread_attr_init(&attr_sql);
pthread_attr_setdetachstate(&attr_sql, PTHREAD_CREATE_DETACHED);
if(pthread_create(&th_sql, &attr_sql, _1thred, mute)!=0)
{
printf(" pthread_create failed login_thread\n");
exit(1);
}
}
void start_3_thread(pthread_mutex_t* mute){
pthread_t th_sql;
pthread_attr_t attr_sql;
pthread_attr_init(&attr_sql);
pthread_attr_setdetachstate(&attr_sql, PTHREAD_CREATE_DETACHED);
if(pthread_create(&th_sql, &attr_sql, _1thred, mute)!=0)
{
printf(" pthread_create failed login_thread\n");
exit(1);
}
}
int main(){
pthread_mutex_t mute;
pthread_mutex_init(&mute, NULL);
start_1_thread(&mute);
start_2_thread(&mute);
start_3_thread(&mute);
while(flag1<NUM){
sleep(1);
printf(".");
fflush(stdout);
}
return 0;}
单核虚拟机:
[lein@localhost ~]$ gcc -o t t2.c -lpthread
[lein@localhost ~]$ ./t
[1964852992] V=28129,from[1522741171.433900] to [1522741171.498049]
3/1
[1954363136] V=22742,from[1522741171.434335] to [1522741171.491243]
3/2
[1943873280] V=20162,from[1522741171.434326] to [1522741171.504722]
3/3
2x4核服务器:
[950908672] V=458015,from[1522741775.032056] to [1522741775.703012]
3/1
[929928960] V=445867,from[1522741775.032025] to [1522741775.712318]
3/2
[940418816] V=440126,from[1522741775.032095] to [1522741775.723419]
3/3
单核的平均值更小,但浮动更大。
原因不得而知,但是,pthread_mutex_lock的效率是远远高于我的代码的。所以,我准备开始用pthread_mutex_lock了。