c - 在全局变量中使用内存映射文件

标签 c operating-system

我为著名的 sleep 理发师问题编写了以下代码,但现在我发现我必须使用内存映射文件而不是全局变量。我怎样才能做到这一点?我不知道内存映射文件。

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h> 
#define MAX_CUSTOMERS 5 

void *customer(void *num);
void *barber(void *);

// CWait is used to make the customer to wait until the barber is done cutting his/her hair.
sem_t CWait;
// waitingRoom Limits the # of customers allowed  to enter the waiting room at one time.
sem_t waitingRoom;
// barberChair ensures mutually exclusive access to the barber chair.
sem_t barberChair;
// barberPillow is used to allow the barber to sleep until a customer arrives.
sem_t barberPillow;

// Flag to stop the barber thread when all customers have been serviced.
int allDone = 0;

int main(int argc, char *argv[])
{
    pthread_t btid;
    pthread_t tid[MAX_CUSTOMERS];
    int i, numChairs;
    int Number[MAX_CUSTOMERS];


    numChairs = MAX_CUSTOMERS;      //number of chairs will be equal to max num of costumers

    printf("A solution to the sleeping barber problem using semaphores.\n");
    for (i = 0; i < MAX_CUSTOMERS; i++) {
        Number[i] = i;
    }

    sem_init(&waitingRoom, 0, numChairs);
    sem_init(&barberChair, 0, 1);
    sem_init(&barberPillow, 0, 0);
    sem_init(&CWait, 0, 0);

    // Create the barber.
    pthread_create(&btid, NULL, barber, NULL);

    // Create the customers.
    for (i = 0; i < MAX_CUSTOMERS; i++) {
        pthread_create(&tid[i], NULL, customer, (void *)&Number[i]);
    }
    // Join each of the threads to wait for them to finish.
    for (i = 0; i < MAX_CUSTOMERS; i++) {
        pthread_join(tid[i],NULL);
    }
    // When all of the customers are finished, kill the barber thread.
    allDone = 1;
    sem_post(&barberPillow); // Wake the barber so he will exit.
    pthread_join(btid,NULL);

    return 0;
}

void *customer(void *number) {
     int num = *(int *)number; // Leave for the shop and take some random amount of  time to arrive.
     sleep(1);
     printf("Customer %d arrived at barber shop.\n", num); // Wait for space to open up in the waiting room...
     sem_wait(&waitingRoom);
     printf("Customer %d entering waiting room.\n", num); // Wait for the barber chair to become free.
     sem_wait(&barberChair); // The chair is free so give up your spot in the  waiting room.
     sem_post(&waitingRoom); // Wake up the barber...
     printf("Customer %d waking the barber.\n", num);
     sem_post(&barberPillow); // Wait for the barber to finish cutting your hair.
     sem_wait(&CWait); // Give up the chair.
     sem_post(&barberChair);
     printf("Customer %d leaving barber shop.\n", num);
}

void *barber(void *junk)
{
// While there are still customers to be serviced... Our barber is omniscient and can tell if there are  customers still on the way to his shop.

  while (!allDone) { // Sleep until someone arrives and wakes you..
    printf("The barber is sleeping\n");
    sem_wait(&barberPillow); // Skip this stuff at the end...
    if (!allDone)
    { // Take a random amount of time to cut the customer's hair.
     printf("The barber is cutting hair\n");
     sleep(1);
     printf("The barber has finished cutting hair.\n"); // Release the customer when done cutting...
     sem_post(&CWait);
    }
    else {
         printf("The barber is going home for the day.\n");
    }
   }
}

最佳答案

使用内存映射文件在单个进程中完全共享有点奇怪,但肯定是可行的。

假设您需要共享一个名为 var_namesome_type_t 类型的读写变量。

首先使用shm_open调用:

var_fd = shm_open("var_name", O_CREAT, S_IRUSR | S_IWUSR)

这会为我们的变量创建一个新的文件描述符。

接下来我们为变量分配空间:

some_type_t *var_ptr;

var_ptr = mmap(NULL, sizeof(some_type_t), PROT_READ | PROT_WRITE, MAP_PRIVATE, var_fd, 0);

您现在可以通过*var_ptr访问该变量;例如*var_ptr = 42

您甚至可以跳过 shm_open 调用,只需执行以下操作:

var_ptr = mmap(NULL, sizeof(some_type_t), PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, 0, 0)

完成后我省略了错误检查和释放变量。

关于c - 在全局变量中使用内存映射文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30538573/

相关文章:

memory-management - 读取指令可能导致的页面错误的最大数量?

当文件位于不同的文件夹中时无法创建项目

C - 为什么当我编译时它无法识别源文件(.c)?

c - 用于循环条件的 fork() 会产生竞争条件吗?

c - Linux中为CFS定义的函数在哪里

windows-vista - 在安装时如何区分Vista SP1和Server 2008

node.js - os.platform() 返回 darwin 而不是 OSX

c - C 中位域结构的大小

c - 这两个将整数分成数字的 while 循环是如何工作的?

无法使用我的目标值检查第一个节点的值,以避免 place_first 函数中的重复