IO线程的同步互斥

1.创建两个线程,分支线程1拷贝文件前半部分,分支线程2拷贝文件后半部分。

#include <head.h>
sem_t sem;
long half_size = 0;  
 
void* product(void *arg) 
{
    FILE *src = fopen("./1.c", "rb");
    FILE *dest = fopen("./2.c.png", "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("./1.c.png", "rb");
    FILE *dest_child = fopen("./2.c.png", "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("./1.c.png", "rb");
    if (src == NULL) 
    {
        perror("打开源文件失败");
        return -1;
    }
    FILE *dest = fopen("./2.c.png", "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 sem1,sem2,sem3;
void* A(void *arg)
{
    while(1)
    {
        //sleep(1);
        sem_wait(&sem1);
        printf("A\n");
        sem_post(&sem2);
    }
    pthread_exit(NULL);
}
void* B(void *arg)
{
    while(1)
    {
        //sleep(1);
        sem_wait(&sem2);
        printf("B\n");
        sem_post(&sem3);
    }
    pthread_exit(NULL);
}
void* C(void*arg)
{
    while(1)
    {
        sem_wait(&sem3);
        printf("C\n");
        sem_post(&sem1);
    }
    pthread_exit(NULL);
}
int main(int argc, const char *argv[])
{
    sem_init(&sem1,0,1);
    sem_init(&sem2,0,0);
    sem_init(&sem3,0,0);
    pthread_t tid1,tid2,tid3;
    if((errno=pthread_create(&tid1,NULL,A,NULL))!=0)
        PRINT_ERROR("pthread_create error");
    if((errno=pthread_create(&tid2,NULL,B,NULL))!=0)
        PRINT_ERROR("pthread_create error");
    if((errno=pthread_create(&tid3,NULL,C,NULL))!=0)
        PRINT_ERROR("pthread_create error");
    pthread_join(tid1,NULL);
    pthread_join(tid2,NULL);
    pthread_join(tid3,NULL);
    sem_destroy(&sem1);
    sem_destroy(&sem2);
    sem_destroy(&sem3);
    return 0;
}
 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值