多任务互斥与同步(互斥锁, 读写锁, 条件变量, 信号量, 命名信号量)
This commit is contained in:
		
							parent
							
								
									d1bc1e2410
								
							
						
					
					
						commit
						7d8e55d275
					
				
							
								
								
									
										83
									
								
								day7/condition.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										83
									
								
								day7/condition.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,83 @@ | ||||
| #include <stdio.h> | ||||
| #include <pthread.h> | ||||
| #include <unistd.h> | ||||
| 
 | ||||
| // 条件变量实例
 | ||||
| 
 | ||||
| // 互斥锁和条件变量的初始化
 | ||||
| pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; | ||||
| pthread_cond_t cond = PTHREAD_COND_INITIALIZER; | ||||
| 
 | ||||
| void *producer_task(void *data) | ||||
| { | ||||
|     int *n = (int *)data; | ||||
|     while (1) | ||||
|     { | ||||
|         pthread_mutex_lock(&mutex); | ||||
| 
 | ||||
|         while (*n == 10) // 只要资源为 10 ,就等待
 | ||||
|         { | ||||
|             // 条件变量等待后,会自动释放 mutex 锁
 | ||||
|             pthread_cond_wait(&cond, &mutex); | ||||
|         } | ||||
| 
 | ||||
|         (*n)++; | ||||
|         printf("生产线程(%ld)生产了 %d 个产品\n", pthread_self(), *n); | ||||
| 
 | ||||
|         // 发出通知,让等待消费的线程恢复(条件满足)
 | ||||
|         pthread_cond_broadcast(&cond); | ||||
| 
 | ||||
|         pthread_mutex_unlock(&mutex); | ||||
|         // usleep(200 * 1000);
 | ||||
|         sleep(1); | ||||
|     } | ||||
| 
 | ||||
|     pthread_exit(NULL); | ||||
| } | ||||
| 
 | ||||
| void *consumer_task(void *data) | ||||
| { | ||||
|     int *n = (int *)data; | ||||
|     while (1) | ||||
|     { | ||||
|         pthread_mutex_lock(&mutex); | ||||
|         while (*n == 0) // 只要资源为 0 ,就等待
 | ||||
|         { | ||||
|             // 条件变量等待后,会自动释放 mutex 锁
 | ||||
|             pthread_cond_wait(&cond, &mutex); | ||||
|         } | ||||
|         printf("消费者(%ld) 消费了 %d 产品\n", pthread_self(), *n); | ||||
|         (*n)--; | ||||
|         pthread_mutex_unlock(&mutex); | ||||
|         // usleep(200 * 1000);
 | ||||
|         sleep(1); | ||||
|     } | ||||
|     pthread_exit(NULL); | ||||
| } | ||||
| 
 | ||||
| int main(int argc, char const *argv[]) | ||||
| { | ||||
|     int num = 3; // 3 个产品
 | ||||
|     pthread_t threads[10]; | ||||
|     // 创建 2 个生产线程
 | ||||
|     for (int i = 0; i < 8; i++) | ||||
|     { | ||||
|         pthread_create(&threads[i], NULL, producer_task, &num); | ||||
|     } | ||||
| 
 | ||||
|     // 创建 3 个消费者线程
 | ||||
|     for (int i = 8; i < 10; i++) | ||||
|     { | ||||
|         pthread_create(&threads[i], NULL, consumer_task, &num); | ||||
|     } | ||||
| 
 | ||||
|     for (int i = 0; i < 10; i++) | ||||
|     { | ||||
|         pthread_join(threads[i], NULL); | ||||
|     } | ||||
| 
 | ||||
|     pthread_mutex_destroy(&mutex); | ||||
|     pthread_cond_destroy(&cond); | ||||
| 
 | ||||
|     return 0; | ||||
| } | ||||
							
								
								
									
										58
									
								
								day7/mutex_1.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								day7/mutex_1.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,58 @@ | ||||
| #include <stdio.h> | ||||
| #include <pthread.h> | ||||
| #include <unistd.h> | ||||
| 
 | ||||
| // 定义两把锁
 | ||||
| pthread_mutex_t mutex1, mutex2; | ||||
| 
 | ||||
| void *task1(void *data) | ||||
| { | ||||
|     char *taskName = (char *)data; | ||||
|     pthread_mutex_lock(&mutex1); | ||||
|     printf("%s 获取锁 1 成功, 等待 1 秒后获取锁 2\n", taskName); | ||||
|     sleep(1); | ||||
|     pthread_mutex_lock(&mutex2); | ||||
|     printf("%s 获取锁 2 成功\n", taskName); | ||||
|     printf("%s\n", taskName); | ||||
| 
 | ||||
|     // 释放锁
 | ||||
|     pthread_mutex_unlock(&mutex2); | ||||
|     pthread_mutex_unlock(&mutex1); | ||||
|     return NULL; | ||||
| } | ||||
| 
 | ||||
| void *task2(void *data) | ||||
| { | ||||
|     char *taskName = (char *)data; | ||||
|     pthread_mutex_lock(&mutex1); | ||||
|     printf("%s 获取锁 1 成功, 等待 1 秒后获取锁 2\n", taskName); | ||||
|     sleep(1); | ||||
|     pthread_mutex_lock(&mutex2); | ||||
|     printf("%s 获取锁 2 成功\n", taskName); | ||||
|     printf("%s\n", taskName); | ||||
| 
 | ||||
|     // 释放锁
 | ||||
|     pthread_mutex_unlock(&mutex2); | ||||
|     pthread_mutex_unlock(&mutex1); | ||||
|     return NULL; | ||||
| } | ||||
| 
 | ||||
| int main(int argc, char const *argv[]) | ||||
| { | ||||
|     // 动态初始化锁
 | ||||
|     pthread_mutex_init(&mutex1, NULL); | ||||
|     pthread_mutex_init(&mutex2, NULL); | ||||
| 
 | ||||
|     // 创建线程
 | ||||
|     pthread_t tid1, tid2; | ||||
|     pthread_create(&tid1, NULL, task1, "hello"); | ||||
|     pthread_create(&tid2, NULL, task2, "world"); | ||||
|     pthread_join(tid1, NULL); | ||||
|     pthread_join(tid2, NULL); | ||||
| 
 | ||||
|     // 销毁锁
 | ||||
|     pthread_mutex_destroy(&mutex1); | ||||
|     pthread_mutex_destroy(&mutex2); | ||||
| 
 | ||||
|     return 0; | ||||
| } | ||||
							
								
								
									
										45
									
								
								day7/named_sem_1.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								day7/named_sem_1.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,45 @@ | ||||
| #include <sys/stat.h> | ||||
| #include <sys/wait.h> | ||||
| #include <fcntl.h> | ||||
| #include <semaphore.h> | ||||
| #include <stdio.h> | ||||
| #include <unistd.h> | ||||
| 
 | ||||
| // 命名信号实例
 | ||||
| 
 | ||||
| void printer(char *msg) | ||||
| { | ||||
|     while (*msg) | ||||
|     { | ||||
|         printf("%c", *msg++); // 打印字符
 | ||||
|         fflush(stdout);       // 刷新控制台
 | ||||
|         sleep(1); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| int main(int argc, char const *argv[]) | ||||
| { | ||||
|     // 命名信号
 | ||||
|     sem_t *sem = sem_open("mysem", O_CREAT | O_RDWR, 0644, 1); | ||||
| 
 | ||||
|     int pid = fork(); | ||||
|     if (pid == 0) // 子进程
 | ||||
|     { | ||||
|         sem_wait(sem); | ||||
|         printer("disen666"); | ||||
|         sem_post(sem); | ||||
|         _exit(0); | ||||
|     } | ||||
|     else if (pid > 0) // 父进程
 | ||||
|     { | ||||
|         sem_wait(sem); | ||||
|         printer("jack888"); | ||||
|         sem_post(sem); | ||||
|         wait(NULL); // 等待子进程退出
 | ||||
| 
 | ||||
|         printf("\n---over---\n"); | ||||
|         sem_close(sem);      // 关闭信号量
 | ||||
|         sem_unlink("mysem"); // 删除信号量文件
 | ||||
|     } | ||||
|     return 0; | ||||
| } | ||||
							
								
								
									
										48
									
								
								day7/named_sem_2.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								day7/named_sem_2.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,48 @@ | ||||
| #include <sys/stat.h> | ||||
| #include <sys/wait.h> | ||||
| #include <fcntl.h> | ||||
| #include <semaphore.h> | ||||
| #include <stdio.h> | ||||
| #include <unistd.h> | ||||
| 
 | ||||
| // 命名信号实例
 | ||||
| 
 | ||||
| void printer(char *msg) | ||||
| { | ||||
|     while (*msg) | ||||
|     { | ||||
|         printf("%c", *msg++); // 打印字符
 | ||||
|         fflush(stdout);       // 刷新控制台
 | ||||
|         sleep(1); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| int main(int argc, char const *argv[]) | ||||
| { | ||||
|     // 命名信号
 | ||||
|     sem_t *sem1 = sem_open("mysem1", O_CREAT | O_RDWR, 0644, 1); | ||||
|     sem_t *sem2 = sem_open("mysem2", O_CREAT | O_RDWR, 0644, 0); | ||||
| 
 | ||||
|     int pid = fork(); | ||||
|     if (pid == 0) // 子进程
 | ||||
|     { | ||||
|         sem_wait(sem1); | ||||
|         printer("disen666"); | ||||
|         sem_post(sem2); | ||||
|         _exit(0); | ||||
|     } | ||||
|     else if (pid > 0) // 父进程
 | ||||
|     { | ||||
|         sem_wait(sem2); | ||||
|         printer("jack888"); | ||||
|         sem_post(sem1); | ||||
| 
 | ||||
|         wait(NULL); // 等待子进程退出
 | ||||
|         printf("\n---over---\n"); | ||||
|         sem_close(sem1);      // 关闭信号量
 | ||||
|         sem_close(sem2);      // 关闭信号量
 | ||||
|         sem_unlink("mysem1"); // 删除信号量文件
 | ||||
|         sem_unlink("mysem2"); // 删除信号量文件
 | ||||
|     } | ||||
|     return 0; | ||||
| } | ||||
							
								
								
									
										34
									
								
								day7/named_sem_3.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								day7/named_sem_3.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,34 @@ | ||||
| #include <sys/stat.h> | ||||
| #include <fcntl.h> | ||||
| #include <semaphore.h> | ||||
| #include <stdio.h> | ||||
| #include <unistd.h> | ||||
| #include <sys/wait.h> | ||||
| 
 | ||||
| // 无血缘关系的进程的互斥
 | ||||
| void printer(char *msg) | ||||
| { | ||||
|     while (*msg) | ||||
|     { | ||||
|         printf("%c", *msg++); | ||||
|         fflush(stdout); | ||||
|         sleep(1); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| int main(int argc, char const *argv[]) | ||||
| { | ||||
|     // 打开信号量文件
 | ||||
|     sem_t *sem = sem_open("mysem", O_CREAT | O_RDWR, 0666, 1); | ||||
| 
 | ||||
|     sem_wait(sem); | ||||
| #ifdef DISEN | ||||
|     printer("disen666\n"); | ||||
| #else | ||||
|     printer("jack888\n"); | ||||
| #endif | ||||
|     sem_post(sem); | ||||
|     sem_close(sem); | ||||
| 
 | ||||
|     return 0; | ||||
| } | ||||
							
								
								
									
										38
									
								
								day7/named_sem_4.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								day7/named_sem_4.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,38 @@ | ||||
| #include <sys/stat.h> | ||||
| #include <fcntl.h> | ||||
| #include <semaphore.h> | ||||
| #include <stdio.h> | ||||
| #include <unistd.h> | ||||
| #include <sys/wait.h> | ||||
| 
 | ||||
| // 无血缘关系的进程的同步
 | ||||
| void printer(char *msg) | ||||
| { | ||||
|     while (*msg) | ||||
|     { | ||||
|         printf("%c", *msg++); | ||||
|         fflush(stdout); | ||||
|         sleep(1); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| int main(int argc, char const *argv[]) | ||||
| { | ||||
|     // 打开信号量文件
 | ||||
|     sem_t *sem1 = sem_open("mysem1", O_CREAT | O_RDWR, 0666, 1); | ||||
|     sem_t *sem2 = sem_open("mysem2", O_CREAT | O_RDWR, 0666, 0); | ||||
| 
 | ||||
| #ifdef DISEN | ||||
|     sem_wait(sem2); | ||||
|     printer("disen666\n"); | ||||
|     sem_post(sem1); | ||||
| #else | ||||
|     sem_wait(sem1); | ||||
|     printer("jack888\n"); | ||||
|     sem_post(sem2); | ||||
| #endif | ||||
| 
 | ||||
|     sem_close(sem1); | ||||
|     sem_close(sem2); | ||||
|     return 0; | ||||
| } | ||||
							
								
								
									
										28
									
								
								day7/nomutex.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								day7/nomutex.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,28 @@ | ||||
| #include <stdio.h> | ||||
| #include <pthread.h> | ||||
| #include <unistd.h> | ||||
| 
 | ||||
| void *printer(void *data) | ||||
| { | ||||
|     char *msg = (char *)data; | ||||
|     while (*msg) | ||||
|     { | ||||
|         printf("%c", *msg++); | ||||
|         fflush(stdout); | ||||
|         sleep(1); | ||||
|     } | ||||
|     return NULL; | ||||
| } | ||||
| 
 | ||||
| int main(int argc, char const **argv) | ||||
| { | ||||
|     pthread_t tid1, tid2; | ||||
|     pthread_create(&tid1, NULL, printer, "disen666\0"); | ||||
|     pthread_create(&tid2, NULL, printer, "lucy888\0"); | ||||
| 
 | ||||
|     pthread_join(tid1, NULL); | ||||
|     pthread_join(tid2, NULL); | ||||
|     printf("---over---\n"); | ||||
| 
 | ||||
|     return 0; | ||||
| } | ||||
							
								
								
									
										42
									
								
								day7/nomutex_2.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								day7/nomutex_2.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,42 @@ | ||||
| #include <stdio.h> | ||||
| #include <pthread.h> | ||||
| #include <unistd.h> | ||||
| 
 | ||||
| // 静态初始化互斥锁
 | ||||
| // pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
 | ||||
| // 动态初始化锁-定义锁
 | ||||
| pthread_mutex_t mutex; | ||||
| 
 | ||||
| void *printer(void *data) | ||||
| { | ||||
| 
 | ||||
|     char *msg = (char *)data; | ||||
|     pthread_mutex_lock(&mutex); // 申请上锁,可能阻塞
 | ||||
|     while (*msg) | ||||
|     { | ||||
|         printf("%c", *msg++); | ||||
|         fflush(stdout); | ||||
|         usleep(200 * 1000); | ||||
|     } | ||||
|     pthread_mutex_unlock(&mutex); // 不解锁,就会发生死锁
 | ||||
|     return NULL; | ||||
| } | ||||
| 
 | ||||
| int main(int argc, char const **argv) | ||||
| { | ||||
|     // 动态初始化锁-初始化
 | ||||
|     pthread_mutex_init(&mutex, NULL); | ||||
| 
 | ||||
|     pthread_t tid1, tid2; | ||||
|     pthread_create(&tid1, NULL, printer, "disen666\n"); | ||||
|     pthread_create(&tid2, NULL, printer, "lucy888\n"); | ||||
| 
 | ||||
|     pthread_join(tid1, NULL); | ||||
|     pthread_join(tid2, NULL); | ||||
|     printf("\n---over---\n"); | ||||
| 
 | ||||
|     // 销毁互斥锁
 | ||||
|     pthread_mutex_destroy(&mutex); | ||||
| 
 | ||||
|     return 0; | ||||
| } | ||||
							
								
								
									
										54
									
								
								day7/nomutex_3.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								day7/nomutex_3.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,54 @@ | ||||
| #include <stdio.h> | ||||
| #include <pthread.h> | ||||
| #include <unistd.h> | ||||
| 
 | ||||
| // 静态初始化互斥锁
 | ||||
| // pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
 | ||||
| // 动态初始化锁-定义锁
 | ||||
| pthread_mutex_t mutex; | ||||
| 
 | ||||
| void *printer(void *data) | ||||
| { | ||||
| 
 | ||||
|     char *msg = (char *)data; | ||||
|     int lock_acquired = 0; // 未获取到锁
 | ||||
|     while (!lock_acquired) // 未获取到锁的时候,循环尝试获取锁,并处理
 | ||||
|     { | ||||
|         // trylock 非阻塞锁
 | ||||
|         if (pthread_mutex_trylock(&mutex) == 0) // 如果拿到锁
 | ||||
|         { | ||||
|             lock_acquired = 1; // 该状态:已获取到锁
 | ||||
|             while (*msg)       // 当前线程传入的字符串未读取完成时,循环读取
 | ||||
|             { | ||||
|                 printf("%c", *msg++); | ||||
|                 fflush(stdout); | ||||
|                 usleep(200 * 1000); | ||||
|             } | ||||
|             pthread_mutex_unlock(&mutex); // 读完后,解锁当前进程
 | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             usleep(100); // 0.1 毫秒后继续尝试获取锁
 | ||||
|         } | ||||
|     } | ||||
|     return NULL; | ||||
| } | ||||
| 
 | ||||
| int main(int argc, char const **argv) | ||||
| { | ||||
|     // 动态初始化锁-初始化
 | ||||
|     pthread_mutex_init(&mutex, NULL); | ||||
| 
 | ||||
|     pthread_t tid1, tid2; | ||||
|     pthread_create(&tid1, NULL, printer, "disen666\n"); | ||||
|     pthread_create(&tid2, NULL, printer, "lucy888\n"); | ||||
| 
 | ||||
|     pthread_join(tid1, NULL); | ||||
|     pthread_join(tid2, NULL); | ||||
|     printf("\n---over---\n"); | ||||
| 
 | ||||
|     // 销毁互斥锁
 | ||||
|     pthread_mutex_destroy(&mutex); | ||||
| 
 | ||||
|     return 0; | ||||
| } | ||||
							
								
								
									
										52
									
								
								day7/rwlock_1.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								day7/rwlock_1.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,52 @@ | ||||
| #include <stdio.h> | ||||
| #include <pthread.h> | ||||
| #include <unistd.h> | ||||
| 
 | ||||
| // 定义读写锁(需要 GNU99)
 | ||||
| pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER; // 静态初始化读写锁
 | ||||
| 
 | ||||
| void *read_task(void *data) | ||||
| { | ||||
|     int *n = (int *)data; | ||||
| 
 | ||||
|     while (1) | ||||
|     { | ||||
|         pthread_rwlock_rdlock(&rwlock); // 申请读锁 rdlock
 | ||||
|         printf("(%ld)线程读取 num: %d\n", pthread_self(), *n); | ||||
|         pthread_rwlock_unlock(&rwlock); // 解锁
 | ||||
|         usleep(500 * 1000); | ||||
|     } | ||||
|     return NULL; | ||||
| } | ||||
| 
 | ||||
| void *write_task(void *data) | ||||
| { | ||||
|     int *n = (int *)data; | ||||
|     while (1) | ||||
|     { | ||||
|         pthread_rwlock_wrlock(&rwlock); // 申请写锁 wrlock
 | ||||
|         (*n)++; | ||||
|         printf("(%ld) 线程写 num: %d\n", pthread_self(), *n); | ||||
|         pthread_rwlock_unlock(&rwlock); // 解锁
 | ||||
|         sleep(2); | ||||
|     } | ||||
| 
 | ||||
|     return NULL; | ||||
| } | ||||
| 
 | ||||
| int main(int argc, char const *argv[]) | ||||
| { | ||||
|     int num; // 公共资源
 | ||||
|     pthread_t t1, t2, t3; | ||||
|     pthread_create(&t1, NULL, read_task, &num); | ||||
|     pthread_create(&t2, NULL, read_task, &num); | ||||
|     pthread_create(&t3, NULL, write_task, &num); | ||||
| 
 | ||||
|     pthread_join(t1, NULL); | ||||
|     pthread_join(t2, NULL); | ||||
|     pthread_join(t3, NULL); | ||||
| 
 | ||||
|     pthread_rwlock_destroy(&rwlock); // 销毁读写锁
 | ||||
| 
 | ||||
|     return 0; | ||||
| } | ||||
							
								
								
									
										97
									
								
								day7/rwlock_2.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										97
									
								
								day7/rwlock_2.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,97 @@ | ||||
| #include <stdio.h> | ||||
| #include <pthread.h> | ||||
| #include <unistd.h> | ||||
| #include <string.h> | ||||
| 
 | ||||
| pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER; | ||||
| int money = 1000;  // 存款余额
 | ||||
| int exit_flag = 0; // 退出标志
 | ||||
| 
 | ||||
| void *task1(void *data) | ||||
| { | ||||
|     while (1) | ||||
|     { | ||||
|         pthread_rwlock_wrlock(&rwlock); // 加写锁
 | ||||
|         // 查询余额
 | ||||
|         printf("存款任务-余额: %d\n", money); | ||||
|         usleep(200 * 1000); | ||||
|         // 从键盘读取存入的金额
 | ||||
|         printf("请输入存款金额 (输入 0 结束存款): "); | ||||
|         fflush(stdout); | ||||
|         int m; | ||||
|         scanf("%d", &m); | ||||
|         if (m == 0) | ||||
|         { | ||||
|             exit_flag = 1; | ||||
|             pthread_rwlock_unlock(&rwlock); // 解锁
 | ||||
|             break; | ||||
|         } | ||||
|         money += m; | ||||
|         // 修改余额并打印结果
 | ||||
|         printf("存款成功, 余额为 %d\n", money); | ||||
|         pthread_rwlock_unlock(&rwlock); // 解锁
 | ||||
|     } | ||||
|     pthread_exit(NULL); | ||||
| } | ||||
| 
 | ||||
| void *task2(void *data) | ||||
| { | ||||
|     while (1) | ||||
|     { | ||||
|         pthread_rwlock_wrlock(&rwlock); // 加写锁
 | ||||
|         // 查询余额
 | ||||
|         printf("取款任务-余额: %d\n", money); | ||||
|         usleep(200 * 1000); | ||||
|         // 从键盘读取取出的金额
 | ||||
|         printf("请输入取款金额 (输入 0 结束取款): "); | ||||
|         fflush(stdout); | ||||
|         int m; | ||||
|         scanf("%d", &m); | ||||
|         if (m == 0) | ||||
|         { | ||||
|             exit_flag = 1; | ||||
|             pthread_rwlock_unlock(&rwlock); // 解锁
 | ||||
|             break; | ||||
|         } | ||||
|         if (money >= m) | ||||
|         { | ||||
|             money -= m; | ||||
|             // 修改余额并打印结果
 | ||||
|             printf("取款成功, 余额为 %d\n", money); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             printf("取款失败, 余额不足\n"); | ||||
|         } | ||||
|         pthread_rwlock_unlock(&rwlock); // 解锁
 | ||||
|     } | ||||
|     pthread_exit(NULL); | ||||
| } | ||||
| 
 | ||||
| int main(int argc, char const *argv[]) | ||||
| { | ||||
|     while (1) | ||||
|     { | ||||
|         pthread_t t1, t2; | ||||
|         pthread_create(&t1, NULL, task1, NULL); | ||||
|         pthread_create(&t2, NULL, task2, NULL); | ||||
| 
 | ||||
|         while (1) | ||||
|         { | ||||
|             pthread_rwlock_rdlock(&rwlock); | ||||
|             if (exit_flag) | ||||
|             { | ||||
|                 pthread_rwlock_unlock(&rwlock); | ||||
|                 break; | ||||
|             } | ||||
|             pthread_rwlock_unlock(&rwlock); | ||||
|         } | ||||
| 
 | ||||
|         pthread_join(t1, NULL); | ||||
|         pthread_join(t2, NULL); | ||||
|     } | ||||
| 
 | ||||
|     pthread_rwlock_destroy(&rwlock); | ||||
| 
 | ||||
|     return 0; | ||||
| } | ||||
							
								
								
									
										48
									
								
								day7/sem_1.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								day7/sem_1.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,48 @@ | ||||
| #include <stdio.h> | ||||
| #include <pthread.h> | ||||
| #include <unistd.h> | ||||
| #include <semaphore.h> | ||||
| 
 | ||||
| // 信号量实例
 | ||||
| 
 | ||||
| sem_t sem; // 定义信号量
 | ||||
| 
 | ||||
| void *printer(void *data) | ||||
| { | ||||
| 
 | ||||
|     char *msg = (char *)data; | ||||
| 
 | ||||
|     // P 操作
 | ||||
|     sem_wait(&sem); // 本案例中锁住了控制台
 | ||||
| 
 | ||||
|     while (*msg) | ||||
|     { | ||||
|         printf("%c", *msg++); | ||||
|         fflush(stdout); | ||||
|         usleep(200 * 1000); | ||||
|     } | ||||
| 
 | ||||
|     // V 操作
 | ||||
|     sem_post(&sem); | ||||
| 
 | ||||
|     return NULL; | ||||
| } | ||||
| 
 | ||||
| int main(int argc, char const **argv) | ||||
| { | ||||
|     // 信号量初始化
 | ||||
|     sem_init(&sem, 0, 1); | ||||
| 
 | ||||
|     pthread_t tid1, tid2; | ||||
|     pthread_create(&tid1, NULL, printer, "disen666\n"); | ||||
|     pthread_create(&tid2, NULL, printer, "lucy888\n"); | ||||
| 
 | ||||
|     pthread_join(tid1, NULL); | ||||
|     pthread_join(tid2, NULL); | ||||
|     printf("\n---over---\n"); | ||||
| 
 | ||||
|     // 销毁信号量
 | ||||
|     sem_destroy(&sem); | ||||
| 
 | ||||
|     return 0; | ||||
| } | ||||
							
								
								
									
										105
									
								
								day7/sem_2.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								day7/sem_2.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,105 @@ | ||||
| #include <stdio.h> | ||||
| #include <pthread.h> | ||||
| #include <unistd.h> | ||||
| #include <string.h> | ||||
| #include <semaphore.h> | ||||
| 
 | ||||
| // 信号量实例 2 - 存取款
 | ||||
| sem_t sem; // 定义信号量
 | ||||
| 
 | ||||
| int money = 1000;  // 存款余额
 | ||||
| int exit_flag = 0; // 退出标志
 | ||||
| 
 | ||||
| void *task1(void *data) | ||||
| { | ||||
|     while (1) | ||||
|     { | ||||
|         sem_wait(&sem); // P 操作
 | ||||
|         // 查询余额
 | ||||
|         printf("存款任务-余额: %d\n", money); | ||||
|         usleep(200 * 1000); | ||||
|         // 从键盘读取存入的金额
 | ||||
|         printf("请输入存款金额 (输入 0 结束存款): "); | ||||
|         fflush(stdout); | ||||
|         int m; | ||||
|         scanf("%d", &m); | ||||
|         if (m == 0) | ||||
|         { | ||||
|             exit_flag = 1; | ||||
|             sem_post(&sem); // V 操作
 | ||||
|             break; | ||||
|         } | ||||
|         money += m; | ||||
|         // 修改余额并打印结果
 | ||||
|         printf("存款成功, 余额为 %d\n", money); | ||||
|         sem_post(&sem); // V 操作
 | ||||
|     } | ||||
|     pthread_exit(NULL); | ||||
| } | ||||
| 
 | ||||
| void *task2(void *data) | ||||
| { | ||||
|     while (1) | ||||
|     { | ||||
|         sem_wait(&sem); // P 操作
 | ||||
|         // 查询余额
 | ||||
|         printf("取款任务-余额: %d\n", money); | ||||
|         usleep(200 * 1000); | ||||
|         // 从键盘读取取出的金额
 | ||||
|         printf("请输入取款金额 (输入 0 结束取款): "); | ||||
|         fflush(stdout); | ||||
|         int m; | ||||
|         scanf("%d", &m); | ||||
|         if (m == 0) | ||||
|         { | ||||
|             exit_flag = 1; | ||||
|             sem_post(&sem); // V 操作
 | ||||
|             break; | ||||
|         } | ||||
|         if (money >= m) | ||||
|         { | ||||
|             money -= m; | ||||
|             // 修改余额并打印结果
 | ||||
|             printf("取款成功, 余额为 %d\n", money); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             printf("取款失败, 余额不足\n"); | ||||
|         } | ||||
|         sem_post(&sem); // V 操作
 | ||||
|     } | ||||
|     pthread_exit(NULL); | ||||
| } | ||||
| 
 | ||||
| int main(int argc, char const *argv[]) | ||||
| { | ||||
|     // 初始化信号量
 | ||||
|     sem_init(&sem, 0, 1); | ||||
| 
 | ||||
|     while (1) | ||||
|     { | ||||
|         pthread_t t1, t2; | ||||
|         pthread_create(&t1, NULL, task1, NULL); | ||||
|         pthread_create(&t2, NULL, task2, NULL); | ||||
| 
 | ||||
|         while (1) | ||||
|         { | ||||
|             sem_wait(&sem); // P 操作
 | ||||
| 
 | ||||
|             if (exit_flag) | ||||
|             { | ||||
|                 sem_post(&sem); // V 操作
 | ||||
|                 break; | ||||
|             } | ||||
|             sem_post(&sem); // V 操作
 | ||||
|         } | ||||
| 
 | ||||
|         pthread_join(t1, NULL); | ||||
|         pthread_join(t2, NULL); | ||||
|     } | ||||
| 
 | ||||
|     // 销毁信号量
 | ||||
|     sem_destroy(&sem); | ||||
| 
 | ||||
|     return 0; | ||||
| } | ||||
							
								
								
									
										88
									
								
								day7/sem_3.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								day7/sem_3.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,88 @@ | ||||
| #include <stdio.h> | ||||
| #include <pthread.h> | ||||
| #include <unistd.h> | ||||
| #include <semaphore.h> | ||||
| #include <string.h> | ||||
| 
 | ||||
| sem_t sem1, sem2; // 信号量
 | ||||
| 
 | ||||
| void *task1(void *data) | ||||
| { | ||||
|     int *money = (int *)data; | ||||
|     // 存款任务
 | ||||
|     sem_wait(&sem1); | ||||
| 
 | ||||
|     //  查询余额
 | ||||
|     printf("存款任务-余额: %d\n", *money); | ||||
|     sleep(1); | ||||
|     // 从键盘读取存入的金额
 | ||||
|     printf("请输入存款金额: "); | ||||
|     fflush(stdout); | ||||
|     int m; | ||||
|     scanf("%d", &m); | ||||
|     *money += m; | ||||
|     // 修改余额并打印结果
 | ||||
|     printf("存款成功, 余额为: %d\n", *money); | ||||
|     sem_post(&sem2); | ||||
|     pthread_exit(NULL); | ||||
| } | ||||
| 
 | ||||
| void *task2(void *data) | ||||
| { | ||||
|     int *money = (int *)data; | ||||
|     // 取款任务
 | ||||
|     sem_wait(&sem2); | ||||
|     //  查询余额
 | ||||
|     printf("取款任务-余额: %d\n", *money); | ||||
| 
 | ||||
|     sleep(1); | ||||
| 
 | ||||
|     // 从键盘读取取出的金额
 | ||||
|     printf("请输入取款金额: "); | ||||
|     fflush(stdout); | ||||
|     int m; | ||||
|     scanf("%d", &m); | ||||
|     if (*money >= m) | ||||
|     { | ||||
|         *money -= m; | ||||
|         // 修改余额并打印结果
 | ||||
|         printf("取款成功, 余额为: %d\n", *money); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         printf("取款失败,余额不足\n"); | ||||
|     } | ||||
| 
 | ||||
|     sem_post(&sem1); | ||||
|     pthread_exit(NULL); | ||||
| } | ||||
| 
 | ||||
| int main(int argc, char const *argv[]) | ||||
| { | ||||
|     // 初始化信号量
 | ||||
|     sem_init(&sem1, 0, 1); // 存款的信号量初始化
 | ||||
|     sem_init(&sem2, 0, 0); // 取款的信号量初始化
 | ||||
| 
 | ||||
|     int money = 1000; // 存款
 | ||||
| 
 | ||||
|     while (1) | ||||
|     { | ||||
|         printf("输入 exit 退出 , 输入其他内容开始存取款\n"); | ||||
|         char input[100]; | ||||
|         scanf("%s", input); | ||||
|         if (strncmp(input, "exit", 4) == 0) | ||||
|         { | ||||
|             break; | ||||
|         } | ||||
|         pthread_t tid1, tid2; | ||||
|         pthread_create(&tid1, NULL, task1, &money); | ||||
|         pthread_create(&tid2, NULL, task2, &money); | ||||
| 
 | ||||
|         pthread_join(tid1, NULL); | ||||
|         pthread_join(tid2, NULL); | ||||
|     } | ||||
| 
 | ||||
|     sem_destroy(&sem1); | ||||
|     sem_destroy(&sem2); | ||||
|     return 0; | ||||
| } | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user