当前位置: 首页 > news >正文

IO学习---->线程

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;//设置标志位取消sleepint 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;
}


http://www.mrgr.cn/news/93887.html

相关文章:

  • QT系列教程(20) Qt 项目视图便捷类
  • 『PostgreSQL』PGSQL备份与还原实操指南
  • 【测试框架篇】单元测试框架pytest(4):assert断言详解
  • 【Linux内核系列】:深入理解缓冲区
  • 《平面几何强化训练题集》第2章5到9题
  • [GHCTF 2025]SQL??? 【sqlite注入】
  • uniapp+Vue3 开发小程序的下载文件功能
  • 选择排序算法OpenMP并行优化
  • 从新手到专家:嵌入式代码空间优化技巧
  • 【组件安装】Rocky 8.10 安装Local License Server 25.03.0 for Linux
  • C/C++中使用CopyFile、CopyFileEx原理、用法、区别及分别在哪些场景使用
  • 从零构建逻辑回归: sklearn 与自定义实现对比
  • [数据结构]并查集--C++版本的实现代码
  • sparkTTS window 安装
  • 数据集构建与训练前准备
  • OpenHarmony5.0分布式系统源码实现分析—软总线
  • C++蓝桥杯皮亚诺曲线距离求解
  • Cline使用MCP-TypeScript版本
  • MCP-代码解读TypeScript版本
  • 尚硅谷TS快速入门笔记(个人笔记用)