#include
#include
/* 主线程:遍历100内奇数 */
/* 子线程:遍历100内偶数 */
/* 主线程等待子线程退出后,输出其退出返回值 */
void *threadRun(void *pretn){
static int i = 0;
for(i=0;i<=100;i++){
if(i%2 == 0)printf("subThread:%d\n",i);
}
pthread_exit(pretn);
}
int main(){
pthread_t thread1;
int arg = 2023;
void *ptemp = &arg;
pthread_create(&thread1,NULL,threadRun,ptemp);
for(int i=0;i<=100;i++){
if(i%2 != 0)printf("Main:%d\n",i);
}
void *p = NULL;
pthread_join(thread1,&p);
printf("subThread return value: %d\n",*(int *)p);
return 0;
}
#include
#include
#include
#include
/* 银行账户 */
typedef struct Account {
int balance; //余额
int (*dramMoney)(int *,int); //取钱方法
int (*saveMoney)(int *,int); //存钱方法(本例未实现)
}Account;
/* 取钱方法实现 */
int dramMoney(int *bal,int cash){
while(*bal>0 && cash>0){ //余额,取钱金额大于0,可以取钱
usleep(20*1000); //由于未进行同步,即使进行条件判断,也会出现错误
*bal -= cash; //取钱:余额=余额-取出的金额
printf("(tid=%ld)Dram Money:%d$ succeed,now balance:%d$\n",pthread_self(),cash,*bal);
}
return *bal;
}
/* 客户取钱(一个线程=一个客户) */
void *customer(void *acc){
Account *ptmp = (Account *)acc;
ptmp->dramMoney(&ptmp->balance,1000);
pthread_exit(acc);
}
int main(){
/* 初始化:账户里有18000 */
Account *acc = (Account *)malloc(sizeof(Account));
acc->balance = 18000;
acc->dramMoney = dramMoney;
/* 创建两个线程模拟两个客户同时取钱 */
pthread_t t1,t2;
pthread_create(&t1,NULL,customer,acc);
pthread_create(&t2,NULL,customer,acc);
pthread_join(t1,NULL);
pthread_join(t2,NULL);
return 0;
}
互斥量(mutex)本质上是一把锁,在访问共享资源前对互斥量进行加锁,访问完成后释放锁。加锁状态下,其他线程阻塞等待,防止多个线程同时访问相同的共享资源。
#include
#include
#include
#include
/* 银行账户 */
typedef struct Account {
int balance; //余额
int (*dramMoney)(int *,int); //取钱方法
int (*saveMoney)(int *,int); //存钱方法(本例未实现)
}Account;
pthread_mutex_t mutex;
/* 取钱方法实现 */
int dramMoney(int *bal,int cash){
while(1){ //余额,取钱金额大于0,可以取钱
pthread_mutex_lock(&mutex);
if(*bal > 0) { //如果未进行同步,即使进行条件判断,也会出现错误
usleep(50 * 1000);
*bal -= cash; //取钱:余额=余额-取出的金额
printf("(tid=%ld)Dram Money:%d$ succeed,now balance:%d$\n", pthread_self(), cash, *bal);
}else{
pthread_mutex_unlock(&mutex);
break;
}
pthread_mutex_unlock(&mutex);
}
return *bal;
}
/* 客户取钱(一个线程=一个客户) */
void *customer(void *acc){
Account *ptmp = (Account *)acc;
ptmp->dramMoney(&ptmp->balance,1000);
pthread_exit(acc);
}
int main(){
pthread_mutex_init(&mutex,NULL);
/* 初始化:账户里有180000 */
Account *acc = (Account *)malloc(sizeof(Account));
acc->balance = 180000;
acc->dramMoney = dramMoney;
/* 创建两个线程模拟两个客户同时取钱 */
pthread_t t1,t2;
pthread_create(&t1,NULL,customer,acc);
pthread_create(&t2,NULL,customer,acc);
pthread_join(t1,NULL);
pthread_join(t2,NULL);
pthread_mutex_destroy(&mutex);
return 0;
}
PS:原先设置账户余额1800,发现cpu速度太快第二个线程还没抢到锁运行就结束,改成18万就能看到线程切换了 如果是ubuntu虚拟机,把cpu设置成1核就可以看到线程切换运行了,前面发现只有单线程再跑,还以为是代码有问题
死锁是指在多进程或多线程下,由于进程/线程之间竞争获取共享资源,导致进程/线程间彼此都相互等待对方释放所持有的资源,使程序所有线程处于无法继续执行的无限等待状态。<如何避免死锁?>规划设计好代码中线程对同步锁的操作,避免嵌套同步、也尽量减少同步资源的定义以避免出现死锁。
条件变量是Linux线程同步和线程通信的一种机制,条件变量可以使线程进入等待,也可以唤醒等待中的进程,以确定何时执行某些操作,例如等待某个资源的可用性;条件变量和互斥量配合使用,可以实现线程同步(线程安全)的线程间通信,也可以解决某个线程长时间得不到锁处于等待状态(线程饥饿)。例如:在多线程环境中实现线程安全的线程间通信,避免同一时间的并发访问共享资源。
用法上很像Java的wait()、notify()实现线程间通信的方法。
#include
#include
#include
#include
/* 银行账户 */
typedef struct Account {
int balance; //余额
int (*dramMoney)(int *,int); //取钱方法
int (*saveMoney)(int *,int); //存钱方法(本例未实现)
}Account;
pthread_mutex_t mutex;
pthread_cond_t cond;
/* 取钱方法实现 */
int dramMoney(int *bal,int cash){
while(1){ //余额,取钱金额大于0,可以取钱
pthread_mutex_lock(&mutex);
pthread_cond_signal(&cond);
if(*bal > 0) {
usleep(50 * 1000); //由于未进行同步,即使进行条件判断,也会出现错误
*bal -= cash; //取钱:余额=余额-取出的金额
printf("(tid=%ld)Dram Money:%d$ succeed,now balance:%d$\n", pthread_self(), cash, *bal);
/* 取完钱等待并释放锁给另一个线程;另一个线程得到锁就上锁再唤醒它,依次循环实现交替执行 */
pthread_cond_wait(&cond,&mutex);
pthread_mutex_unlock(&mutex);
}else{
pthread_mutex_unlock(&mutex);
break;
}
}
return *bal;
}
/* 客户取钱(一个线程=一个客户) */
void *customer(void *acc){
Account *ptmp = (Account *)acc;
ptmp->dramMoney(&ptmp->balance,1000);
pthread_exit(acc);
}
int main(){
pthread_mutex_init(&mutex,NULL);
pthread_cond_init(&cond,NULL);
/* 初始化:账户里有90000 */
Account *acc = (Account *)malloc(sizeof(Account));
acc->balance = 9000;
acc->dramMoney = dramMoney;
/* 创建两个线程模拟两个客户同时取钱 */
pthread_t t1,t2;
pthread_create(&t1,NULL,customer,acc);
pthread_create(&t2,NULL,customer,acc);
pthread_join(t1,NULL);
pthread_join(t2,NULL);
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&cond);
return 0;
}