将读写锁放到共享内存中,实现进程之间对数据的读写访问控制

代码

#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <assert.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <fstream>
#include <iostream>
#include <sstream>

/**
 *  返回一片共享内存标识符,用于后续获取该共享内存,以及销毁该共享内存
 *  file_name
 *  md5
 */
namespace hhh{
    namespace hhh{
        class mutex_function{
        public:
            mutex_function() = default;
            // 定义进程锁结构体
//            typedef struct mutex_struct{
//                pthread_mutex_t lock;
//                pthread_mutexattr_t lock_attr;
//                int memory_addr;
//            }mutex_struct_t;

            typedef struct mutex_struct{
                pthread_rwlock_t lock;
                pthread_rwlockattr_t lock_attr;
                int memory_addr;
            }mutex_struct_t;

            //create memory_addr
            int create_share_memory_id(const int INDEX_OF_KEY,size_t md5){
                const char* FILE_PATH = "/home/gsc/Projects";
                key_t id = ftok(FILE_PATH,md5);
                const int share_memory_id = shmget(id,md5,IPC_CREAT | 0666);
                if (share_memory_id == -1){
                    std::cout << "share_memory_id error!\n" << std::endl;
                    exit(EXIT_FAILURE);
                }else{
                    return share_memory_id;
                }
            }

            // 初始化进程锁结构体
//            int init_mutex_struct(mutex_struct_t* mutex_ptr){
//                pthread_mutexattr_init(&(mutex_ptr->lock_attr));
//                pthread_mutexattr_setpshared(&(mutex_ptr->lock_attr),PTHREAD_PROCESS_SHARED);
//                pthread_mutex_init(&(mutex_ptr->lock),&(mutex_ptr->lock_attr));
//                return 0;
//            }

            int init_mutex_struct(mutex_struct_t* mutex_ptr){
                pthread_rwlockattr_init(&(mutex_ptr->lock_attr));
                pthread_rwlockattr_setpshared(&(mutex_ptr->lock_attr),PTHREAD_PROCESS_SHARED);
                pthread_rwlock_init(&(mutex_ptr->lock),&(mutex_ptr->lock_attr));
                return 0;
            }
            // 在共享内存上定义进程锁结构体并且返回其位置
            mutex_struct_t* mutex_struct_addr(const int INDEX){
                int memory_id = create_share_memory_id(INDEX,sizeof (mutex_struct_t));
                mutex_struct_t * share_ptr = (mutex_struct_t* )shmat(memory_id, 0, 0);
                if (share_ptr == (void *)-1){
                    std::cout << "share_ptr error!\n" << std::endl;
                    exit(EXIT_FAILURE);
                }
                share_ptr->memory_addr = memory_id;
                assert(init_mutex_struct(share_ptr)== 0);
                return share_ptr;
            }

            // 销毁进程锁结构体,利用其memory_addr变量索引到其占用的共享内存并销毁
//            const int destory_mutex_struct(mutex_struct_t * mutex_struct){
//                pthread_mutex_destroy(&(mutex_struct->lock));
//                pthread_mutexattr_destroy(&(mutex_struct->lock_attr));
//                assert(shmctl(mutex_struct->memory_addr,IPC_RMID, nullptr) == 0);
//                return 0;
//            }

            const int destory_mutex_struct(mutex_struct_t * mutex_struct){
                pthread_rwlock_destroy(&(mutex_struct->lock));
                pthread_rwlockattr_destroy(&(mutex_struct->lock_attr));
                assert(shmctl(mutex_struct->memory_addr,IPC_RMID, nullptr) == 0);
                return 0;
            }
        public:
            size_t share_memory_id;
            mutex_struct_t* mutex_struct_ptr;
        };

    }//namespace hhh
}//namespace hhh

//read file
void read_file(const std::string file_name,int id){
    std::ifstream fp(file_name,std::ios::binary);
    std::stringstream ss;
    ss << fp.rdbuf();

    std::cout << "线程"<< id << "抢占了资源,输出:" << ss.str() << std::endl;
    sleep(3);
    std::cout << "线程"<< id << "释放了资源...\n" << std::endl;
    fp.close();
}

int main(){
    std::string file_name = "/home/gsc/Projects/1.txt";
    // 创建自定义进程锁
    hal::hsm::mutex_function mutex_function_object;
    mutex_function_object.mutex_struct_ptr = mutex_function_object.mutex_struct_addr(111);

    // 获取一片共享内存空间
    int memory_addr = mutex_function_object.create_share_memory_id(222,sizeof (int));
    volatile int* x = (int*)shmat(memory_addr, 0, 0);
    // 创建新进程
    int id = fork();
    assert(id >= 0);

    // 设置循环次数
    const int N = 1000000;

    // 父进程每次加1,子进程每次加2
    int i;
    for (i = 0; i < N; ++i) {

        if (id > 0) {  // 父进程
            // 加锁
//            pthread_mutex_lock(&(mutex_function_object.mutex_struct_ptr->lock));
//            pthread_rwlock_rdlock(&(mutex_function_object.mutex_struct_ptr->lock));
            pthread_rwlock_wrlock(&(mutex_function_object.mutex_struct_ptr->lock));

//            int temp = *x;
//            *x = temp+1;
            read_file(file_name,getpid());
            // 解锁
            pthread_rwlock_unlock(&(mutex_function_object.mutex_struct_ptr->lock));

        } else {  // 子进程
            // 加锁
//            pthread_mutex_lock(&(mutex_function_object.mutex_struct_ptr->lock));
//            pthread_rwlock_rdlock(&(mutex_function_object.mutex_struct_ptr->lock));
            pthread_rwlock_wrlock(&(mutex_function_object.mutex_struct_ptr->lock));

//            int temp = *x;
//            *x = temp+2;
            read_file(file_name,getpid());
            // 解锁
//            pthread_mutex_unlock(&(mutex_function_object.mutex_struct_ptr->lock));
            pthread_rwlock_unlock(&(mutex_function_object.mutex_struct_ptr->lock));

        }

    }

    // 等待循环完毕
    sleep(1);

    // 打印
//    printf("pid= %d, x_address= %x, x= %d\n", getpid(), x, *x);

    // 等待打印完毕
    sleep(1);

    // 销毁进程锁,释放申请的共享内存
    if (id > 0) {  // 父进程
        mutex_function_object.destory_mutex_struct((mutex_function_object.mutex_struct_ptr));
        mutex_function_object.mutex_struct_ptr = nullptr;
        shmctl(memory_addr, IPC_RMID, nullptr);
        x = nullptr;
        printf("父进程释放资源完毕\n");
    }

    return 0;
}

猜你喜欢

转载自blog.csdn.net/CHYabc123456hh/article/details/112272785