读者写者问题 代码

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <windows.h>
#include <io.h>
#include <conio.h>
#include  <stdlib.h>
#include <fstream>
using namespace std;

#define READER 'R'  //读者
#define WRITER 'W'  //写者
#define DELAY_TIME 700  //最基本的延迟时间,其他都为他的倍数
#define MAX_THREAD_NUM 64 //最大线程数
int readercount = 0; //读者数量
int writercount = 0; //写者数量
//临界区
CRITICAL_SECTION RP_Write;
CRITICAL_SECTION WP_Write;
CRITICAL_SECTION WP_Read;
//线程结构体
struct Thread{
    int serial;  //线程序号
    char entity;   //判断是读者线程还是写者线程
    double delay;   //线程延迟
    double persist; //线程写操作持续时间
};
//读者优先 读者进程
void RP_ReaderThread(void *p){
    //互斥变量
    HANDLE h_Mutex;
    h_Mutex = OpenMutex(MUTEX_ALL_ACCESS,false,"mutex");
    DWORD m_delay = (DWORD)(((Thread*)(p))->delay*DELAY_TIME); //延迟时间
    DWORD m_persist = (DWORD)(((Thread*)(p))->persist*DELAY_TIME);  //读文件持续时间 用来模拟线程活动
    int m_serial = ((Thread*)(p))->serial; //线程号
    Sleep(m_delay);
    cout<<"读者线程 "<<m_serial<<" 发送读请求"<<endl;

    WaitForSingleObject(h_Mutex,-1);//修改互斥信号量

    readercount++;//读者增加
    if(readercount==1){
        //第一个读者等待资源
        EnterCriticalSection(&RP_Write);
    }
    ReleaseMutex(h_Mutex);
    //读文件
    cout<<"读者线程 "<<m_serial<<" 开始读文件。"<<endl;
    Sleep(m_persist);
    //退出线程
    cout<<"读者线程 "<<m_serial<<" 已读完文件。"<<endl;

    //改变互斥信号量
    WaitForSingleObject(h_Mutex,-1);

    readercount--;
    if(readercount==0){
        //如果所有读者读完,唤醒写者
        LeaveCriticalSection(&RP_Write);
    }
    ReleaseMutex(h_Mutex);//释放信号量
}
//读者优先 写者进程
void RP_WriterThread(void *p){
    DWORD m_delay= (((Thread*)(p))->delay*DELAY_TIME);; //延迟时间
    DWORD m_persist= (((Thread*)(p))->persist*DELAY_TIME);;  //读文件持续时间 用来模拟线程活动
    int m_serial=((Thread*)(p))->serial;; //线程号
    Sleep(m_delay);
    cout<<"写者线程 "<<m_serial<<" 发送写请求。"<<endl;
    //等待资源分配给自己
    EnterCriticalSection(&RP_Write);

    cout<<"写者线程 "<<m_serial<<" 开始写文件。"<<endl;
    Sleep(m_persist);
    cout<<"写者线程 "<<m_serial<<" 已写完文件。"<<endl;
    LeaveCriticalSection(&RP_Write);//释放资源
}
//读者优先处理函数
void ReaderPriority(char *file){
    DWORD n_thread=0; //线程数目
    DWORD thread_ID; //线程ID

    //信号量
    HANDLE h_Mutex;
    h_Mutex=CreateMutex(NULL,false,"mutex");
    //存取线程的数组
    HANDLE h_Thread[MAX_THREAD_NUM];
    Thread threads[MAX_THREAD_NUM];

    readercount = 0;//初始化读者数量
    InitializeCriticalSection(&RP_Write);//初始化临界区
    //打开文件
    ifstream inFile;
    inFile.open(file);
    cout<<"读者优先:"<<endl;
    cout<<endl;
    //获取文件内容
    while(inFile){
        inFile>>threads[n_thread].serial;
        inFile>>threads[n_thread].entity;
        inFile>>threads[n_thread].delay;
        inFile>>threads[n_thread++].persist;
        inFile.get();
    }
    for(int i=0;i<(int)(n_thread);i++){
        if(threads[i].entity==READER||threads[i].entity=='r')
        {
            //创建读者线程
            h_Thread[i]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(RP_ReaderThread),&threads[i],0,&thread_ID);
        }
        else
            //创建写者线程
            h_Thread[i]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(RP_WriterThread),&threads[i],0,&thread_ID);
    }
    //等待所有线程结束
    WaitForMultipleObjects(n_thread,h_Thread,true,-1);
    cout<<"所有的读者和写者完成各自操作。"<<endl;
}

//写者优先 读者进程
void WP_ReaderThread(void *p)
{
    //互斥变量
    HANDLE h_Mutex1;
    h_Mutex1 = OpenMutex(MUTEX_ALL_ACCESS,false,"mutex1");
    HANDLE h_Mutex2;  //互斥信号量 保证对readercount的访问和修改互斥
    h_Mutex2 = OpenMutex(MUTEX_ALL_ACCESS,false,"mutex2");
    DWORD m_delay = (DWORD)(((Thread*)(p))->delay*DELAY_TIME);
    DWORD m_persist = (DWORD)(((Thread*)(p))->persist*DELAY_TIME);
    int m_serial = ((Thread*)(p))->serial;
    Sleep(m_delay);//延迟等待
    cout<<"读者线程 "<<m_serial<<" 发送读请求"<<endl;

    WaitForSingleObject(h_Mutex1,-1);

    //读者进入临界区
    EnterCriticalSection(&WP_Read);
    WaitForSingleObject(h_Mutex2,-1);
    readercount++;//读者的数目增加
    if(readercount==1){
        //第一个读者等待资源,等待读者写完
        EnterCriticalSection(&WP_Write);
    }
    ReleaseMutex(h_Mutex2); //释放信号量
    //使其他读者进入
    LeaveCriticalSection(&WP_Read);
    ReleaseMutex(h_Mutex1);
    //读文件
    cout<<"读者线程 "<<m_serial<<" 开始读文件。"<<endl;
    Sleep(m_persist);
    //退出线程
    cout<<"读者线程 "<<m_serial<<" 已读完文件。"<<endl;
    //修改互斥信号量
    WaitForSingleObject(h_Mutex2,-1);

    readercount--;
    if(readercount==0){
        //如果所有读者读完,唤醒写者
        LeaveCriticalSection(&WP_Write);
    }
    ReleaseMutex(h_Mutex2);//释放信号量
}
//写者优先 写者进程
void WP_WriterThread(void *p){
    DWORD m_delay;
    DWORD m_persist;
    int m_serial;
    //互斥信号量
    HANDLE h_Mutex3;
    h_Mutex3 = OpenMutex(MUTEX_ALL_ACCESS,false,"mutex3");

    //从参数中获取信息
    m_serial=((Thread*)(p))->serial;
    m_delay = (((Thread*)(p))->delay*DELAY_TIME);
    m_persist = (((Thread*)(p))->persist*DELAY_TIME);
    Sleep(m_delay);
    cout<<"写者线程 "<<m_serial<<" 发送写请求。"<<endl;
    WaitForSingleObject(h_Mutex3,-1);//修改互斥信号量
    writercount++;//写者数目增加
    if(writercount==1){
        //第一个写者申请并等待资源
        EnterCriticalSection(&WP_Read);
    }
    ReleaseMutex(h_Mutex3);//释放信号量
    EnterCriticalSection(&WP_Write); //等待资源分配给自己

    cout<<"写者线程 "<<m_serial<<" 开始写文件。"<<endl;
    Sleep(m_persist);
    cout<<"写者线程 "<<m_serial<<" 已写完文件。"<<endl;
    //唤醒其他等待的写者
    LeaveCriticalSection(&WP_Write);
    WaitForSingleObject(h_Mutex3,-1);//修改互斥信号量
    writercount--;
    if(writercount==0){
        //写者数目为0,唤醒读者
        LeaveCriticalSection(&WP_Read);
    }
    ReleaseMutex(h_Mutex3);
}
//写者优先处理函数
void WriterPriority(char *file){
    DWORD n_thread=0; //线程数目
    DWORD thread_ID;//线程ID
    //创建相应临界区
    HANDLE h_Mutex1;
    h_Mutex1=CreateMutex(NULL,false,"mutex1");
    HANDLE h_Mutex2;
    h_Mutex2=CreateMutex(NULL,false,"mutex2");
    HANDLE h_Mutex3;
    h_Mutex3=CreateMutex(NULL,false,"mutex3");

    //创建线程数组
    HANDLE h_Thread[MAX_THREAD_NUM];
    Thread threads[MAX_THREAD_NUM];
    //初始化计数器和临界区
    readercount = 0;
    writercount = 0;
    InitializeCriticalSection(&WP_Write);
    InitializeCriticalSection(&WP_Read);
    //打开文件
    ifstream inFile;
    inFile.open(file);
    cout<<"写者优先:"<<endl;
    cout<<endl;
    //获取文件内容
    while(inFile){
        inFile>>threads[n_thread].serial;
        inFile>>threads[n_thread].entity;
        inFile>>threads[n_thread].delay;
        inFile>>threads[n_thread++].persist;
        inFile.get();
    }
    for(int i=0;i<(int)(n_thread);i++){
        if(threads[i].entity==READER||threads[i].entity=='r')
        {
            //创建读者线程
            h_Thread[i]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(RP_ReaderThread),&threads[i],0,&thread_ID);
        }
        else
            //创建写者线程
            h_Thread[i]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(RP_WriterThread),&threads[i],0,&thread_ID);
    }
     WaitForMultipleObjects(n_thread,h_Thread,true,-1);
    cout<<"所有的读者和写者完成各自操作。"<<endl;
}
int main(){
    int num;
    int cnt = 0;
    while(1){
        cout<<"************************************"<<endl;
        cout<<endl;
        cout<<"|             1.读者优先            |"<<endl;
        cout<<"|             2.写者优先            |"<<endl;
        cout<<"|             3.退出程序            |"<<endl;
        cout<<endl;
        cout<<"************************************"<<endl;
start:
        cout<<"请输入你所要进行的选择:"<<endl;
        cin>>num;
        if(num<1||num>3)
        {
            cout<<"输入无效,请重新输入"<<endl;
            goto start;
        }
        else if(num==1){
            ReaderPriority("thread.txt");
        }
        else if(num==2){
            WriterPriority("thread.txt");
        }
        else if(num==3)
        {
            exit(0);
        }
        system("pause");
        system("cls");
    }
    system("pause");
    return 0;
}

thread中的内容为

1 R 3 5
2 W 4 5
3 R 5 2
4 R 6 5
5 W 5.1 3

6 W 3 5
7 W 16 5
8 R 5 2 
9 W 6 5
10 R 4 3
11 R 17 7

以下是C语言实现读者写者问题代码,使用信号量机制: 引用:使用POSIX信号量机制解决读者-写者问题C语言实现,读者和写者进程数量可设置。[^1] ```c #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <pthread.h> #include <fcntl.h> #include <semaphore.h> #include <sys/mman.h> #define FILE_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) // 全局变量 static sem_t *r_lock; // 读者锁 static sem_t *rw_lock; // 写者锁 static int *read_cnt; // 读者数量计数器 static int *data; // 共享数据区 // 读者线程 void *reader(void *arg) { int id = *(int *)arg; while (1) { // 读者锁加锁 sem_wait(r_lock); (*read_cnt)++; if (*read_cnt == 1) { sem_wait(rw_lock); } // 读者锁解锁 sem_post(r_lock); // 读取数据 printf("Reader %d is reading data: %d\n", id, *data); // 读者锁加锁 sem_wait(r_lock); (*read_cnt)--; if (*read_cnt == 0) { sem_post(rw_lock); } // 读者锁解锁 sem_post(r_lock); // 等待一段时间 sleep(rand() % 3 + 1); } return NULL; } // 写者线程 void *writer(void *arg) { int id = *(int *)arg; while (1) { // 写者锁加锁 sem_wait(rw_lock); // 写入数据 (*data)++; printf("Writer %d is writing data: %d\n", id, *data); // 写者锁解锁 sem_post(rw_lock); // 等待一段时间 sleep(rand() % 3 + 1); } return NULL; } int main(int argc, char *argv[]) { // 获取参数 if (argc != 3) { printf("usage: %s <reader_num> <writer_num>\n", argv); exit(1); } int reader_num = atoi(argv); int writer_num = atoi(argv); // 创建共享内存 int fd = shm_open("/shm", O_CREAT | O_RDWR, FILE_MODE); ftruncate(fd, sizeof(sem_t) * 2 + sizeof(int) * 2); r_lock = mmap(NULL, sizeof(sem_t), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); rw_lock = mmap(NULL, sizeof(sem_t), PROT_READ | PROT_WRITE, MAP_SHARED, fd, sizeof(sem_t)); read_cnt = mmap(NULL, sizeof(int), PROT_READ | PROT_WRITE, MAP_SHARED, fd, sizeof(sem_t) * 2); data = mmap(NULL, sizeof(int), PROT_READ | PROT_WRITE, MAP_SHARED, fd, sizeof(sem_t) * 2 + sizeof(int)); // 初始化信号量 sem_init(r_lock, 1, 1); sem_init(rw_lock, 1, 1); // 创建读者线程 pthread_t tid[reader_num + writer_num]; int index = 0; for (int i = 0; i < reader_num; i++) { int *id = malloc(sizeof(int)); *id = ++index; pthread_create(&tid[i], NULL, reader, id); } // 创建写者线程 for (int i = 0; i < writer_num; i++) { int *id = malloc(sizeof(int)); *id = ++index; pthread_create(&tid[reader_num + i], NULL, writer, id); } // 等待线程结束 for (int i = 0; i < reader_num + writer_num; i++) { pthread_join(tid[i], NULL); } // 销毁信号量 sem_destroy(r_lock); sem_destroy(rw_lock); // 删除共享内存 munmap(r_lock, sizeof(sem_t)); munmap(rw_lock, sizeof(sem_t)); munmap(read_cnt, sizeof(int)); munmap(data, sizeof(int)); shm_unlink("/shm"); return 0; } ``` 引用:使用System V信号量机制解决读者-写者问题C语言实现,读者和写者进程数量可设置。 ```c #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <pthread.h> #include <sys/sem.h> #include <sys/ipc.h> #include <sys/shm.h> #include <sys/types.h> // 定义信号量操作 static struct sembuf sem_r_lock = { {0, 0, SEM_UNDO}, {0, 1, SEM_UNDO}, }; static struct sembuf sem_r_unlock = { {0, -1, SEM_UNDO}, }; static struct sembuf sem_rw_lock = { {1, 0, SEM_UNDO}, {0, 0, SEM_UNDO}, }; static struct sembuf sem_rw_unlock = { {1, -1, SEM_UNDO}, }; // 全局变量 static int sem_id; // 信号量ID static int *read_cnt; // 读者数量计数器 static int *data; // 共享数据区 // 读者线程 void *reader(void *arg) { int id = *(int *)arg; while (1) { // 读者锁加锁 semop(sem_id, sem_r_lock, 2); (*read_cnt)++; if (*read_cnt == 1) { semop(sem_id, sem_rw_lock, 2); } // 读者锁解锁 semop(sem_id, sem_r_unlock, 1); // 读取数据 printf("Reader %d is reading data: %d\n", id, *data); // 读者锁加锁 semop(sem_id, sem_r_lock, 2); (*read_cnt)--; if (*read_cnt == 0) { semop(sem_id, sem_rw_unlock, 1); } // 读者锁解锁 semop(sem_id, sem_r_unlock, 1); // 等待一段时间 sleep(rand() % 3 + 1); } return NULL; } // 写者线程 void *writer(void *arg) { int id = *(int *)arg; while (1) { // 写者锁加锁 semop(sem_id, sem_rw_lock, 2); // 写入数据 (*data)++; printf("Writer %d is writing data: %d\n", id, *data); // 写者锁解锁 semop(sem_id, sem_rw_unlock, 1); // 等待一段时间 sleep(rand() % 3 + 1); } return NULL; } int main(int argc, char *argv[]) { // 获取参数 if (argc != 3) { printf("usage: %s <reader_num> <writer_num>\n", argv); exit(1); } int reader_num = atoi(argv); int writer_num = atoi(argv); // 创建共享内存 int shmid = shmget(IPC_PRIVATE, sizeof(int) * 2, IPC_CREAT | 0666); read_cnt = (int *)shmat(shmid, 0, 0); data = read_cnt + 1; // 初始化共享内存 *read_cnt = 0; *data = 0; // 创建信号量 sem_id = semget(IPC_PRIVATE, 2, IPC_CREAT | 0666); semctl(sem_id, 0, SETVAL, 1); semctl(sem_id, 1, SETVAL, 1); // 创建读者线程 pthread_t tid[reader_num + writer_num]; int index = 0; for (int i = 0; i < reader_num; i++) { int *id = malloc(sizeof(int)); *id = ++index; pthread_create(&tid[i], NULL, reader, id); } // 创建写者线程 for (int i = 0; i < writer_num; i++) { int *id = malloc(sizeof(int)); *id = ++index; pthread_create(&tid[reader_num + i], NULL, writer, id); } // 等待线程结束 for (int i = 0; i < reader_num + writer_num; i++) { pthread_join(tid[i], NULL); } // 删除信号量 semctl(sem_id, 0, IPC_RMID, 0); // 删除共享内存 shmdt(read_cnt); shmctl(shmid, IPC_RMID, 0); return 0; } ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值