1.练习一
练习:请在linux 利用c语言编程实现两个线程按照顺序依次输出”ABABABAB......" (信雅达)
例如a线程输出”A”之后b线程输出”B”,然后a线程输出“A”,再b线程输出”B”,之后往复循环。
1.1信号量写法
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
// 利用信号量实现两个线程按照顺序一次输出ABABABAB
// 信号量
sem_t sem1;
sem_t sem2;
void *outa(void *arg)
{
while (1)
{
sleep(1);
// 申请资源,初始sem2信号量为1,a运行,
// 输出A 之后,sem2 变为 0
// 如果sem2为0, a阻塞
sem_wait(&sem2);
printf("A");
// 输出A 之后,释放资源,sem1变为1
sem_post(&sem1);
}
}
void *outb(void *arg)
{
while (1)
{
sleep(1);
// 申请资源,初始sem1信号量为0,b阻塞,
// 如果sem1为1, b运行
// 输出完B 之后,sem1 变为
sem_wait(&sem1);
printf("B ");
// 输出 B 之后,释放资源,sem2变为1
sem_post(&sem2);
putchar('\n');
}
}
int main(int argc, char const *argv[])
{
// 线程标识
pthread_t tid1, tid2;
// 初始化信号量
sem_init(&sem1, 0, 0);
sem_init(&sem2, 0, 1);
// 创建线程并判断
if (pthread_create(&tid1, NULL, outa, NULL) != 0)
{
perror("tid1 err");
return -1;
}
if (pthread_create(&tid2, NULL, outb, NULL) != 0)
{
perror("tid2 err");
return -1;
}
// 回收线程
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
return 0;
}
1.2互斥锁加条件变量写法
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
// 利用互斥所与条件变量实现两个线程按照顺序一次输出ABABABAB
// 定义全局条件变量与锁,条件变量用于线程间通信
pthread_mutex_t lock;
pthread_cond_t cond;
void *funA(void *arg)
{
for (int i = 0; i < 10; i++)
{
sleep(2);
pthread_mutex_lock(&lock); // 上锁
printf("A");
fflush(NULL); // 刷新
pthread_cond_signal(&cond); // 发信号,此时线程b可以输出b
pthread_mutex_unlock(&lock); // 解锁
}
pthread_exit(NULL);
}
void *funB(void *arg)
{
for (int i = 0; i < 10; i++)
{
pthread_mutex_lock(&lock); // 上锁
// 请求条件,没有条件时阻塞,等待线程a发出信号后,解除阻塞
pthread_cond_wait(&cond, &lock);
printf("B ");
fflush(NULL);
pthread_mutex_unlock(&lock);
}
putchar('\n');
pthread_exit(NULL);
}
int main(int argc, char const *argv[])
{
// 线程标识
pthread_t tid1, tid2;
// 初始化条件变量
pthread_cond_init(&cond, NULL);
// 创建线程
if (pthread_create(&tid1, NULL, funA, NULL) < 0)
{
perror("tid1 err");
return -1;
}
if (pthread_create(&tid2, NULL, funB, NULL) < 0)
{
perror("tid1 err");
return -1;
}
// 初始化互斥锁
pthread_mutex_init(&lock, NULL);
// 判断互斥锁是否初始化成功
if (pthread_mutex_init(&lock, NULL) != 0)
{
perror(" init error");
return -1;
}
// 回收线程
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
return 0;
}