多任务互斥与同步(互斥锁, 读写锁, 条件变量, 信号量, 命名信号量)
This commit is contained in:
parent
d1bc1e2410
commit
7d8e55d275
|
@ -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;
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
|
@ -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…
Reference in New Issue