首页 > 其他分享 >线程同步-读者写者问题(多线程)

线程同步-读者写者问题(多线程)

时间:2022-11-09 11:15:54浏览次数:50  
标签:readcount int void 写者 线程 printf rmutex sem 多线程

任务描述:
0 推荐在openEuer上实现 1 描述操作系统中“读者-写者”问题,理解问题的本质,提交你理解或查找到的文本资料 2 利用多线程完成reader 和writer 3 在main中测试若干个reader 和writer的测试,提交截图说明代码的正确性

  • 如果一个进程正在某个文件上写入内容,而另一个进程也同时开始在同一文件上写入内容,则系统将进入不一致状态。在特定的时间仅应允许一个进程更改文件中存在的数据的值。
  • 另一个问题是,如果一个进程正在读取文件,而另一个进程同时在同一文件上写入,则可能会导致读取不干净,因为在该文件上写入的进程会更改文件的值,但是读取该文件的过程将读取文件中存在的旧值。因此,应避免这种情况。
 

 

 

1.问题描述
有两组并发进程:读者和写者,共享一个文件F,要求:
- 允许多个读者同时执行读操作
- 任一写者在完成写操作之前不允许其它读者或写者工作
- 写者执行写操作前,应让已有的写者和读者全部退出

2.问题分析

- 共享数据(文件、记录)由Reader和Writer是两组并发进程共享
- Reader和Writer两组并发进程
- 同组的Reader进程可同时对文件进行读,不用互斥
- 写-写互斥
- 读-写互斥

对于线程,有以下流程:定义--创建初始化-线程运行函数--线程退出

对于信号量,有以下流程:定义--创建初始化--信号量wait和signal--信号量销毁


代码实现
实现多读者(多线程)操作
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>
 
sem_t rmutex,wmutex;
static void *readerThread(void *arg);
static void *reader3Thread(void *arg);
static void *reader2Thread(void *arg);
static void *writerThread(void *arg);
int readcount = 0;
int n = 0;
int nowLen = 1;
char contentArticle[10][100];
int main(){
 
    pthread_t readerTidp,writerTidp,reader3Tidp,reader2Tidp;
    void *retval;
    
    if(sem_init(&rmutex,0,1)==-1||sem_init(&wmutex,0,1)==-1){
        printf("sem_init error\n");
        return -1;
    }//init semaphore
 
    if(pthread_create(&readerTidp,NULL,readerThread,NULL) !=0||pthread_create(&writerTidp,NULL,writerThread,NULL) !=0||pthread_create(&reader3Tidp,NULL,reader3Thread,NULL) !=0||pthread_create(&reader2Tidp,NULL,reader2Thread,NULL) !=0){
        printf("pthread_create error\n");
        return -2;
    }//init pthread
 
    pthread_join(readerTidp,&retval);
    pthread_join(reader3Tidp,&retval);
    pthread_join(reader2Tidp,&retval);
    pthread_join(writerTidp,&retval);
 
    sem_destroy(&rmutex);
    sem_destroy(&wmutex);
    return 0;
}
 
static void *readerThread(void *arg){
    for(int i = 0;i < 10;i++)
    {
        sem_wait(&rmutex);
        if(readcount == 0)sem_wait(&wmutex);
        readcount = readcount+1;
        sem_post(&rmutex);
    
        //read operatiom
        printf("\n\nI'm reader first Reader thread :...the global variable  n equals to %d\n",n);
        for(int j = 0;j < nowLen-1;j++)
        {
            for(int k = 0;k < 26;k++)
                printf("%c",contentArticle[j][k]);
            printf("\n");
        }
            printf("now the count 0f reader is %d\n",readcount);
        printf("now the length 0f content is %d\n",nowLen-1);
        sleep(5);
 
        sem_wait(&rmutex);
        readcount = readcount-1;
        if(readcount == 0)sem_post(&wmutex);
        sem_post(&rmutex);
        sleep(1);
    }
}
 
static void *reader3Thread(void *arg){
        for(int i = 0;i < 10;i++)
        {
                sem_wait(&rmutex);
                if(readcount == 0)sem_wait(&wmutex);
                readcount = readcount+1;
                sem_post(&rmutex);
 
                //read operatiom
                printf("\n\nI'm reader third  Reader thread :...the global variable  n equals to %d\n",n);
        for(int j = 0;j < nowLen-1;j++)
                {
                      for(int k = 0;k < 26;k++)
                                printf("%c",contentArticle[j][k]);
                        printf("\n");
                }
                printf("now the count 0f reader is %d\n",readcount);
                printf("now the length 0f content is %d\n",nowLen-1);
 
        sleep(5);
                sem_wait(&rmutex);
                readcount = readcount-1;
                if(readcount == 0)sem_post(&wmutex);
                sem_post(&rmutex);
                sleep(8);
        }
}
 
 
static void *reader2Thread(void *arg){
        for(int i = 0;i < 10;i++)
        {
                sem_wait(&rmutex);
                if(readcount == 0)sem_wait(&wmutex);
                readcount = readcount+1;
                sem_post(&rmutex);
 
                //read operatiom
                printf("\n\nI'm reader second Reader thread :...the global variable  n equals to %d\n",n);
        for(int j = 0;j < nowLen-1;j++)
              {
                        for(int k = 0;k < 26;k++)
                                printf("%c",contentArticle[j][k]);
                        printf("\n");
                }
 
                printf("now the count 0f reader is %d\n",readcount);
                printf("now the length 0f content is %d\n",nowLen-1);
 
 
                sem_wait(&rmutex);
                readcount = readcount-1;
                if(readcount == 0)sem_post(&wmutex);
                sem_post(&rmutex);
                sleep(4);
        }
}
 
 
 
static void *writerThread(void *arg){
        for(int i = 0;i < 10;i++)
        {
                sem_wait(&wmutex);
              
               //writer operation 
               n = n+1;
        for(int k = 0;k < 26;k++)
        contentArticle[nowLen-1][k] = 'z'-k;
        nowLen++;
        printf("\n\nWriter thread :writing opration the global variable  n equals to  %d \n",n);
                sleep(2);
               sem_post(&wmutex);
                sleep(3);
        }
}

代码运行截图如下:

 

标签:readcount,int,void,写者,线程,printf,rmutex,sem,多线程
From: https://www.cnblogs.com/syf0105/p/16872908.html

相关文章

  • js线程机制与事件机制
    基于尚硅谷的尚硅谷JavaScript高级教程提供笔记撰写,加入一些个人理解github源码博客下载线程与进程进程程序的一次执行,它占有一片独有的内存空间可以通过windows......
  • Linux多线程开发
    1.线程线程概述与进程(process)类似,线程(thread)是允许应用程序并发执行多个任务的一种机制。一个进程可以包含多个线程。同一个程序中的所有线程均会独立执行相同程序,且共享......
  • 从排队上厕所来看线程池的线程分配和处理
      德州站旁边,王二经营一家厕所服务公司,为公众提供便民入厕服务。车站每天人来人往。人越多,自然,王二的生意就越好。王二这里固定提供3间厕所,当超过3人用厕时,后面的人就排队......
  • day 22- 线程的礼让,优先级,守护线程
    线程的礼让利用Thread.yield()使线程进行礼让礼让的概念:礼让线程,让当前正在执行的线程暂停,但并不是阻塞将线程从运行状态转化为就绪状态线程礼让是由cpu调度,并......
  • 读者-写者(多线程)
    目录问题描述问题分析伪代码伪代码描述相关函数代码实现问题描述有读者和写者两个并发进程,共享一个文件,当两个或以上的读进程同时访问共享数据时不会产生副作用,但若某......
  • SimpleDateFormat线程安全问题排查
    一.问题现象运营部门反馈使用小程序配置的拉新现金红包活动二维码,在扫码后跳转至404页面。二.原因排查首先,检查扫码后的跳转链接地址不是对应二维码的实际URL,根据代......
  • Linux系统编程——守护进程+线程
    在学习Linux系统编程总结了笔记,并分享出来。有问题请及时联系博主:​​Alliswell_WP​​,转载请注明出处。09-linux-day08(守护进程-线程)目录:一、学习目标二、守护进程1、守......
  • Linux系统编程——09-linux-day08(守护进程-线程)
    在学习Linux系统编程总结了笔记,并分享出来。有问题请及时联系博主:​​Alliswell_WP​​,转载请注明出处。09-linux-day08(守护进程-线程)  一、学习目标1、守护进程的特点2......
  • Linux系统编程——09-linux-day09(线程同步)
    在学习Linux系统编程总结了笔记,并分享出来。有问题请及时联系博主:​​Alliswell_WP​​,转载请注明出处。09-linux-day09(线程同步)  一、内容回顾1、守护进程:运行在后台,脱离......
  • 操作系统学习笔记——进程管理(进程与线程)
    在学习操作系统时对进程管理(进程与线程)特别困惑,所以总结了笔记,并分享出来,特别是蓝色和红色字体。有问题请及时联系博主:​​Alliswell_WP​​,转载请注明出处。 重点难点:进程......