编写一个C程序,模拟银行转账操作,使用线程和同步机制确保操作的原子性和一致性。
时间: 2024-10-21 16:13:10 浏览: 37
在C语言中,要编写一个银行转账操作的程序并使用线程和同步机制,我们可以利用互斥锁(mutex)来保证并发环境下的数据一致性和原子性。以下是一个简单的示例,假设我们有两个账户,每个账户有一个余额字段,以及两个线程分别代表存款和取款操作。
```c
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <semaphore.h> // 使用信号量
#define MAX_BALANCE 10000
#define ACCOUNTS 2
typedef struct {
int id;
int balance;
pthread_mutex_t lock; // 互斥锁
sem_t sem; // 信号量,用于控制操作顺序
} Account;
Account accounts[ACCOUNTS];
void* deposit_thread(void *arg) {
int amount = *(int*)arg;
int account_id = (int)(arg % ACCOUNTS); // 随机选择账户
pthread_mutex_lock(&accounts[account_id].lock);
accounts[account_id].balance += amount;
printf("Deposit: Thread %d, Account %d, New Balance: %d\n",
pthread_self(), account_id, accounts[account_id].balance);
pthread_mutex_unlock(&accounts[account_id].lock);
sem_post(&accounts[account_id].sem); // 解锁后通知取款线程
return NULL;
}
void* withdraw_thread(void *arg) {
int amount = *(int*)arg;
int account_id = (int)(arg % ACCOUNTS); // 随机选择账户
pthread_mutex_lock(&accounts[account_id].lock);
if (accounts[account_id].balance >= amount) {
accounts[account_id].balance -= amount;
printf("Withdrawal: Thread %d, Account %d, New Balance: %d\n",
pthread_self(), account_id, accounts[account_id].balance);
} else {
printf("Insufficient funds.\n");
}
pthread_mutex_unlock(&accounts[account_id].lock);
sem_post(&accounts[account_id].sem); // 解锁后通知存款线程
return NULL;
}
int main() {
pthread_t deposit_thread_id, withdraw_thread_id;
int amounts[] = {500, 750}; // 存款和取款金额
for (int i = 0; i < ACCOUNTS; i++) {
accounts[i].id = i;
accounts[i].balance = MAX_BALANCE / 2;
pthread_mutex_init(&accounts[i].lock, NULL);
sem_init(&accounts[i].sem, 0, 0); // 初始化为0,表示没有操作进行
}
// 创建并启动存款和取款线程
for (int i = 0; i < sizeof(amounts)/sizeof(amounts[0]); i++) {
pthread_create(&deposit_thread_id, NULL, deposit_thread, &amounts[i]);
pthread_create(&withdraw_thread_id, NULL, withdraw_thread, &amounts[i]);
pthread_join(deposit_thread_id, NULL);
pthread_join(withdraw_thread_id, NULL);
}
for (int i = 0; i < ACCOUNTS; i++) {
pthread_mutex_destroy(&accounts[i].lock);
sem_destroy(&accounts[i].sem);
}
return 0;
}
```
在这个例子中:
1. 我们创建了两个互斥锁 `lock` 和两个信号量 `sem` 分别保护每个账户的余额。
2. `deposit_thread` 和 `withdraw_thread` 函数模拟了存款和取款操作,它们获取账户对应的锁,执行操作,然后释放锁并通知其他线程。
3. 信号量用来协调线程的执行顺序,确保先完成的操作得到解锁,让另一个操作能够继续。
阅读全文