多线程的同步和互斥—线程的信号量
同步:
//account.h #ifndef _ACCOUNT_H #define _ACCOUNT_H #include <pthread.h> #include <semaphore.h> typedef struct{ int code; double balance; //定义一把互斥锁,用来对多线程操作的银行账户(共享资源)进行加锁(保护)的 /* 建议一把互斥锁和一个共享资源(银行账户)绑定,尽量不要设置成全局变量,否则可能出现 一把互斥锁去锁几百个账户(即一个线程获得锁,其他线程将阻塞),导致并发性的降低 */ sem_t sem; }Account; //创建账户 extern Account *create_account(int code, double balance); //销毁账户 extern void destroy_account(Account *a); //取款 extern double get_momney(Account *a, double momney); //存款 extern double save_momney(Account *a, double momney); //获得余额 extern double get_balance(Account *a); #endif
//accout.c #include "account.h" #include <stdlib.h> #include <stdio.h> #include <unistd.h> //创建账户 Account *create_account(int code, double balance) { Account *a = (Account *)malloc(sizeof(Account)); if(a == NULL){ printf("create_account failed\n"); return (Account *)0; } a->code = code; a->balance = balance; sem_init(&a->sem, 0, 1);//信号量初始为1 return a; } //销毁账户 extern void destroy_account(Account *a) { if(a == NULL){ printf("destroy_account failed\n"); } sem_destroy(&a->sem); free(a); } //取款 extern double get_momney(Account *a, double momney) { if(a == NULL){ printf("get_momney failed\n"); } //P sem_wait(&a->sem); if(momney < 0 || a->balance < momney) { printf("momney not enough\n"); //V sem_post(&a->sem); return 0.0; } double balance = a->balance; sleep(1); balance = balance - momney; a->balance = balance; //V sem_post(&a->sem); return momney; } //存款 extern double save_momney(Account *a, double momney) { if(a == NULL){ printf("save_momney failed\n"); } //P sem_wait(&a->sem); if(momney < 0){ //V sem_post(&a->sem); return 0.0; } double balance = a->balance; sleep(1); balance = balance + momney; a->balance = balance; //V sem_post(&a->sem); return momney; } //获得余额 extern double get_balance(Account *a) { if(a == NULL){ printf("get_balance failed\n"); } //P sem_wait(&a->sem); double balance = a->balance; //V sem_post(&a->sem); return balance; }
同步:
//cal.c #include <stdio.h> #include <pthread.h> #include <unistd.h> #include <semaphore.h> typedef struct { int res; sem_t sem; }ResArg; void *cal_fn(void *arg) { ResArg *result = (ResArg *)arg; int i = 0; int sum = 0; for(i = 0;i <101; i++){ sum +=i; } result->res = sum; sleep(1); //V sem_post(&result->sem); printf("v operate\n"); (void *)0; } void *get_fn(void *arg) { ResArg *result = (ResArg *)arg; //P sem_wait(&result->sem); printf("P operate\n"); printf("reslt = %d\n",result->res); (void *)0; } int main(void) { int err; pthread_t cal,get; ResArg r; sem_init(&r.sem, 0, 0);//初始值为0 if(pthread_create(&cal,NULL,cal_fn,(void *)&r) != 0){ printf("cal pthread creat fail\n"); } if(pthread_create(&get,NULL,get_fn,(void *)&r) != 0){ printf("get pthread creat fail\n"); } pthread_join(cal,NULL); pthread_join(get,NULL); sem_destroy(&r.sem); return 0; }