2023.3.2作业

文章提供了三个示例,分别使用条件变量和信号量实现特定的多线程同步问题。任务一使用信号量实现字符串的翻转打印;任务二通过条件变量保证线程按特定顺序ABC打印;任务三则用信号量控制字符串打印和反转的交替进行。所有示例都基于C语言的pthread库。
摘要由CSDN通过智能技术生成

1.将一个文件中的数据打印到终端上,类似cat一个文件。要求如下

a. A线程读取文件中的数据

b.B线程将A线程读取到的数据打印到终端上

c.文件打印完毕后,结束进程.

2.用条件变量实现,有编号为ABC的三个线程,线程内分别打印自己的线程编号,要求打印的顺序为ABC.

a,提示: 多个条件变量

3.要求用信号量的方式实现,打印一次倒置一次。不允许使用flag.

提示: 用多个信号量

任务一

#include<stdio.h>
#include<semaphore.h>
#include<pthread.h>
#include<string.h>
#include<stdlib.h>
#define ERR_MSG(msg) {fprintf(stderr,"错误的行数可能为%d\n",__LINE__);\
    perror(msg);}
sem_t number;
char arr[8];
void* PrintNo1(void*a)
{
    int size=strlen(arr);
    char InheritData;
    while(1)
    {
        if(0==sem_wait(&number))         //No1线程第一次P操作
        {
            if(0==sem_wait(&number))      //No1线程第二次P操作
            {
                printf("%s\n",arr);
            }
            sem_post(&number);              //No1线程第一次V操作
            for(int i=0;i<(size/2);i++)
            {
                InheritData=*(arr+i);
                *(arr+i)=*(arr+size-1-i);
                *(arr+size-i-1)=InheritData;
            }
        }
        sem_post(&number);              //No1线程第二次V操作
    }
}
int main(int argc, const char *argv[])
{
    //构造信号量
    strcpy(arr,"1234567");
    sem_init(&number,0,3);
    
    //创建子程序*3
    pthread_t No1,No2,No3;
    pthread_create(&No1,NULL,PrintNo1,arr);
 
    //等待程序退出
    pthread_join(No1,NULL);  
    sem_destroy(&number);                  //清除缓存
    return 0;
}

输出效果图如下:

其中,打印的文本中内容

任务二

代码如下图

#include<stdio.h>
#include<semaphore.h>
#include<pthread.h>
#include<string.h>
#include<unistd.h>
#include<stdlib.h>
#define ERR_MSG(msg) {fprintf(stderr,"错误的行数可能为%d\n",__LINE__);\
    perror(msg);}
//互斥锁
pthread_mutex_t lock;
//关系锁
int key=0;   // 0先输出1线程  1先输出2线程  2先输出3线程
pthread_cond_t mvlock1;
pthread_cond_t mvlock2;
pthread_cond_t mvlock3;
//
void* PrintNo1(void*nothing)
{
    while(1)
    {
        //创建互斥锁
        pthread_mutex_lock(&lock);
        if(key!=0)
        {
            //创建互动锁
            pthread_cond_wait(&mvlock1,&lock);
        }
            sleep(1);
            system("echo \033[05m \033[31m");
            printf("这是No1线程\n");
//            system("echo \033[05m \033[31m");
        //切换互动条件
        key=1;
        //互动
        pthread_cond_signal(&mvlock2);
        //关闭互斥锁
        pthread_mutex_unlock(&lock);
    }
}

void* PrintNo2(void*nothing)
{
    //char* arr=a;
    while(1)
    {
        //创建互斥锁
        pthread_mutex_lock(&lock);
        if(key!=1)
        {
            //创建互动锁
            pthread_cond_wait(&mvlock2,&lock);
        }
        sleep(1);
        system("echo \033[05m \033[30m");
        printf("这是No2线程\n");
    //        system("echo \033[05m \033[31m")

        //切换互动条件
        key=2;
        //互动
        pthread_cond_signal(&mvlock3);
        //关闭互斥锁
        pthread_mutex_unlock(&lock);
    };
}


void* PrintNo3(void*nothing)
{
    while(1)
    {
        //创建互斥锁
        pthread_mutex_lock(&lock);
        if(key!=2)
        {
            //创建互动锁
            pthread_cond_wait(&mvlock3,&lock);
        }
        sleep(1);
            system("echo \033[05m \033[32m");
        printf("这是No3线程\n");

        //切换互动条件
        key=0;
        //互动
        pthread_cond_signal(&mvlock1);
        //关闭互斥锁
        pthread_mutex_unlock(&lock);

    }
}

int main(int argc, const char *argv[])
{
    //创建互斥锁
    pthread_mutex_init(&lock,NULL);
    //创建互动锁
    pthread_cond_init(&mvlock1,NULL);
    pthread_cond_init(&mvlock2,NULL);
    pthread_cond_init(&mvlock3,NULL);
    //创建子程序*3
    pthread_t No1,No2,No3;
    pthread_create(&No1,NULL,PrintNo1,NULL);
    pthread_create(&No2,NULL,PrintNo2,NULL);
    pthread_create(&No3,NULL,PrintNo3,NULL);



    //等待程序退出
    pthread_join(No1,NULL);
    pthread_join(No2,NULL);
    pthread_join(No3,NULL);
    
    pthread_mutex_destroy(&lock);
    pthread_cond_destroy(&mvlock1);
    pthread_cond_destroy(&mvlock2);
    return 0;
}

输出实物如下图

任务三

代码如下图:

#include<stdio.h>
#include<semaphore.h>
#include<pthread.h>
#include<string.h>
#include<stdlib.h>
#define ERR_MSG(msg) {fprintf(stderr,"错误的行数可能为%d\n",__LINE__);\
    perror(msg);}
sem_t number;
char arr[8];
void* PrintNo1(void*a)
{
    int size=strlen(arr);
    char InheritData;
    while(1)
    {
        if(0==sem_wait(&number))         //No1线程P操作
        {
            if(0==sem_wait(&number))
            {
                printf("%s\n",arr);
            }
            sem_post(&number);
            for(int i=0;i<(size/2);i++)
            {
                InheritData=*(arr+i);
                *(arr+i)=*(arr+size-1-i);
                *(arr+size-i-1)=InheritData;
            }
        }
        sem_post(&number);              //No1线程V操作
    }
}
/*
void* PrintNo2(void*a)
{
    //char* arr=a;
    int size=strlen(arr);
    char InheritData;
    while(1)
    {
        if(0==sem_wait(&number))          //No2线程P操作
        {
            if(0==sem_wait(&number))       //No2线程二次P操作
            {
                for(int i=0;i<(size/2);i++)
                {
                    InheritData=*(arr+i);
                    *(arr+i)=*(arr+size-1-i);
                    *(arr+size-i-1)=InheritData;
                }
            
            };
            sem_post(&number);           //No2线程第一次V操作
        };
        sem_post(&number);                //No2线程第二次V操作
    };
}
*/
/*
void* PrintNo3(void*nothing)
{
    while(1)
    {
        if(sem_wait(&number)<0)            //No3线程P操作
        {
            printf("这是No3线程\n");
        }    
        sem_post(&number);                //No3线程V操作
    }

}
*/
int main(int argc, const char *argv[])
{
    //构造信号量
    strcpy(arr,"1234567");
    sem_init(&number,0,3);
    //printf("%d\n",sem_wait(&number));
    
    //创建子程序*3
    pthread_t No1,No2,No3;
    pthread_create(&No1,NULL,PrintNo1,arr);
    //pthread_create(&No2,NULL,PrintNo2,arr);
    //pthread_create(&No3,NULL,PrintNo3,NULL);




    //等待程序退出
    pthread_join(No1,NULL);
    //pthread_join(No2,NULL);
    //pthread_join(No3,NULL);
    

    sem_destroy(&number);                  //清除缓存
    return 0;
}

输出实物图图下图所示:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值