我必须使用线程进行一些银行帐户转账并对不同结果进行基准测试。我认为普通锁的同步方案的时间肯定比一账户一锁的方案差。
这是我使用通用锁的实现:
pthread_mutex_t general_mutex;
typedef struct {
int id;
double balance;
} Account;
int NThreads = 400; /*Threads number*/
#define N 20 /*Accounts number*/
Account accounts[N];
void transfer(double money, Account* origin, Account* destini) {
pthread_mutex_lock(&general_mutex); //Init general lock.
bool wasPosible = withdraw(origin, money);
if (wasPosible ) deposit(destini, money);
pthread_mutex_unlock(&general_mutex); //End general lock.
}
以下是每个帐户单独锁定的实现:
typedef struct {
int id;
double balance;
pthread_mutex_t mutex; // lock to use/modify vars
} Account;
int NThreads = 400; /*Threads number*/
#define N 20 /*Accounts number*/
Account accounts[N];
void transfer(double money, Account* origin, Account* destini) {
if (from->id < to->id) {
pthread_mutex_lock(&(origin->mutex));
pthread_mutex_lock(&(destini->mutex));
} else {
pthread_mutex_lock(&(destini->mutex));
pthread_mutex_lock(&(origin->mutex));
}
bool wasPosible = withdraw(origin, money);
if (wasPosible ) deposit(destini, amount);
pthread_mutex_unlock(&(origin->mutex));
pthread_mutex_unlock(&(destini->mutex));
}
为什么一般的锁方案比第二种方案花费的时间更少?
谢谢
最佳答案
锁定操作不是免费的。在第二个示例中,您执行的锁定/解锁操作是第一个示例的两倍。其他操作似乎都是简单的内存访问,因此它们不会持续很长时间。
我的观点是,在您的系统中,您在锁上花费的时间比实际处理的时间多,因此增加锁的数量并不相关。如果传输
使用磁盘或网络等慢速IO,情况可能会有所不同。
顺便说一句,正如您在评论中所说,400 个线程的效率可能再次低于小得多的数量。经验法则是与您将使用的核心数量一样多,如果处理花费时间等待 io,则增加一个可变因子 - 如果没有 io 永远不会超过可用核心。上限是所有线程使用的内存不得超过您想要使用的内存,并且启动和同步线程的开销远低于总处理时间。
关于c - 使用线程进行银行账户转账,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54921634/