1.创建两个线程,分支线程1拷贝文件的前一部分,分支线程2拷贝文件的后一部分
#include <head.h>
sem_t sem;
long half_size = 0; // 全局变量,供所有线程共享
void* product(void *arg)
{
FILE *src = fopen("IO.text", "rb");
FILE *dest = fopen("IO1.text", "rb+");
if (src == NULL || dest == NULL)
{
perror("文件打开失败");
pthread_exit(NULL);
}
char buf[128] = {0};
size_t n;
while ((n = fread(buf, 1, sizeof(buf), src)) > 0)
{
if (ftell(src) > half_size)
{
n -= (ftell(src) - half_size); // 防止越界写入
}
if (fwrite(buf, 1, n, dest) != n)
{
perror("线程1写入失败");
fclose(src);
fclose(dest);
pthread_exit(NULL);
}
if (ftell(src) >= half_size)
{
break; // 退出循环,完成前半部分写入
}
}
printf("线程1完成文件前半部分的拷贝。\n");
fclose(src);
fclose(dest);
sem_post(&sem); // 通知消费者线程
pthread_exit(NULL);
}
void* consumer(void *arg)
{
sem_wait(&sem); // 等待生产者完成前半部分
FILE *src_child = fopen("IO.text", "rb");
FILE *dest_child = fopen("IO1.text", "rb+");
if (src_child == NULL || dest_child == NULL)
{
perror("文件打开失败");
pthread_exit(NULL);
}
fseek(src_child, half_size, SEEK_SET);
fseek(dest_child, half_size, SEEK_SET);
char buf[128] = {0};
size_t n;
while ((n = fread(buf, 1, sizeof(buf), src_child)) > 0)
{
if (fwrite(buf, 1, n, dest_child) != n)
{
perror("线程2写入失败");
fclose(src_child);
fclose(dest_child);
pthread_exit(NULL);
}
}
printf("线程2完成文件后半部分的拷贝。\n");
fclose(src_child);
fclose(dest_child);
pthread_exit(NULL);
}
int main(int argc, const char *argv[])
{
FILE *src = fopen("IO.text", "rb");
if (src == NULL)
{
perror("打开源文件失败");
return -1;
}
FILE *dest = fopen("IO1.text", "wb");
if (dest == NULL)
{
perror("打开目标文件失败");
fclose(src);
return -1;
}
// 计算文件大小和一半位置
fseek(src, 0, SEEK_END);
long file_size = ftell(src);
rewind(src);
half_size = file_size / 2;
sem_init(&sem, 0, 0);
pthread_t tid1, tid2;
if ((errno = pthread_create(&tid1, NULL, product, NULL)) != 0)
{
perror("pthread_create error");
}
if ((errno = pthread_create(&tid2, NULL, consumer, NULL)) != 0)
{
perror("pthread_create error");
}
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
sem_destroy(&sem);
fclose(src);
fclose(dest);
return 0;
}
2.创建3个线程,线程A打印A,线程B打印B,线程C打印C,要求重复打印顺序ABC (分别使用信号量和条件变量实现)
#include <head.h>
//创建信号量
sem_t sema;
sem_t semb;
sem_t semc;
void* pta(void* arg)
{
while(1)
{
//sleep(1);
sem_wait(&sema);
printf("A\n");
sem_post(&semb);
}
pthread_exit(NULL);
}
void* ptb(void* arg)
{
while(1)
{
//sleep(1);
sem_wait(&semb);
printf("B\n");
sem_post(&semc);
}
pthread_exit(NULL);
}
void* ptc(void* arg)
{
while(1)
{
sleep(1);
sem_wait(&semc);
printf("C\n");
sem_post(&sema);
}
pthread_exit(NULL);
}
int main(int argc, const char *argv[])
{
sem_init(&sema,0,1);
sem_init(&semb,0,0);
sem_init(&semc,0,0);
pthread_t std1,std2,std3;
if((errno=pthread_create(&std1,NULL,pta,NULL))!=0)
PRINT_ERROR("pthread_create error");
if((errno=pthread_create(&std2,NULL,ptb,NULL))!=0)
PRINT_ERROR("pthread_create error");
if((errno=pthread_create(&std3,NULL,ptc,NULL))!=0)
PRINT_ERROR("pthread_create error");
pthread_join(std1,NULL);
pthread_join(std2,NULL);
pthread_join(std3,NULL);
sem_destroy(&sema);
sem_destroy(&semb);
sem_destroy(&semc);
return 0;
}
#include <head.h>
//定义并初始化条件变量
pthread_cond_t cond3 =PTHREAD_COND_INITIALIZER;
pthread_cond_t cond1 =PTHREAD_COND_INITIALIZER;
pthread_cond_t cond2 =PTHREAD_COND_INITIALIZER;
//定义并初始化互斥锁
pthread_mutex_t mutex=PTHREAD_MUTEX_INITIALIZER;
//设置标志位取消sleep
int flag =0;
//pthread_cond_t cond;
//pthread_cond_init(&cond,NULL);
void* pta(void *arg)
{
while(1)
{
// sleep(1);//放弃CPU资源,使cpu一定先使用消费者线程
pthread_mutex_lock(&mutex);
if(flag!=0)
pthread_cond_wait(&cond3,&mutex);
printf("A\n");
flag=1;
pthread_cond_signal(&cond1);
pthread_mutex_unlock(&mutex);
}
pthread_exit(NULL);
}
void* ptb(void *arg)
{
while(1)
{
//上锁
pthread_mutex_lock(&mutex);
if(flag!=1)
//阻塞休眠并解锁
pthread_cond_wait(&cond1,&mutex);
printf("B\n");
flag=2;
//解锁
pthread_mutex_unlock(&mutex);
pthread_cond_signal(&cond2);
}
pthread_exit(NULL);
}
void* ptc(void *arg)
{
while(1)
{
//上锁
pthread_mutex_lock(&mutex);
if(flag!=2)
//阻塞休眠并解锁
pthread_cond_wait(&cond2,&mutex);
printf("C\n");
flag=0;
//解锁
pthread_mutex_unlock(&mutex);
pthread_cond_signal(&cond3);
}
pthread_exit(NULL);
}
int main(int argc, const char *argv[])
{
pthread_t std1,std2,std3,std4,std5;
if( (errno=pthread_create(&std1,NULL,pta,NULL))!=0)
{
PRINT_ERROR("pthread_create error");
}
if((errno=pthread_create(&std2,NULL,ptb,NULL))!=0)
{
PRINT_ERROR("pthread_create error");
}
if((errno=pthread_create(&std3,NULL,ptc,NULL))!=0)
{
PRINT_ERROR("pthread_create error");
}
pthread_join(std1,NULL);
pthread_join(std2,NULL);
pthread_join(std3,NULL);
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&cond3);
pthread_cond_destroy(&cond1);
pthread_cond_destroy(&cond2);
return 0;
}