shmget:找不到共享内存...在Mac OS终端中工作,但在Linux中工作

时间:2018-12-11 06:07:12

标签: c++ linux semaphore shared-memory

说明:我正在尝试使用共享内存和信号量的程序,以允许多个子进程操纵共享内存中的共享数据。我在xcode上编写了该程序,它在mac os终端中运行良好,但给了我shmget:在Linux中找不到共享内存。

运行ipcs时,我注意到它确实创建了共享内存并标记为删除,但是重新启动似乎无济于事。我必须手动删除一个。即使那样,它仍然不起作用。但是,Mac OS终端运行正常,程序甚至可以运行...我不知道该如何解决。请帮忙。非常感谢!!!

#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <iostream>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <unistd.h>
#include <random>
#include <chrono>
#include <sys/sem.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
using namespace std;

/*************************************************************************
 ***************** CONSTANT AND STRUCT DECLARATIONS **********************
 *************************************************************************/
#define RESOURCES 4             /* Number of Resources */
#define PROCESS 10              /* Number of child process */
#define LOOP_NUMBER 5          /* Number of Loops per process */

struct Memory {                 /* Structure to store resources */
    float var[RESOURCES];
};


/*************************************************************************
 **************************** FUNCTIONS **********************************
 *************************************************************************/
/* Function: sem_lock. Locks the semaphore for exclusive access to shared memory region.
 * input: semaphore ID, process ID
 * output: none
 */
int sem_lock(int resource_number, int semID, int process_id) {
    /* structure for semaphore operation */
    struct sembuf sem_op;
    
    /* wait on semaphore, unless it's value is non-negative. */
    sem_op.sem_num = 0;
    sem_op.sem_op = -1;
    sem_op.sem_flg = 0;
    //cout << "Process " << process_id << " locks." << endl;
    //semop  (semID, &sem_op, 1);
    return
    semop  (semID, &sem_op, 1);
}

/* function: sem_unlock. Unlocks the semaphore.
 * input: semaphore ID, process ID
 * output: none
 */
void sem_unlock(int resource_number, int semID,  int process_id) {
    /* structure for semaphore operation */
    struct sembuf sem_op;
    
    /* wait on semaphore, unless it's value is non-negative. */
    sem_op.sem_num = 0;
    sem_op.sem_op = 1;
    sem_op.sem_flg = 0;
    //cout << "Process " << process_id << " unlocks." << endl;
    //semop (semID, &sem_op, 1);
    semop  (semID, &sem_op, 1);
}

/*************************************************************************
**************************** MAIN ****************************************
**************************************************************************/
int main (int argc, char *argv[]) {
    pid_t childPid[PROCESS];
    key_t ShmKey, semKey;
    int ShmID,semID;
    int rc;                         /* return value of system calls. */
    struct Memory *mPtr;
    union semun {                   /* semaphore value, for semctl() */
        int val;
        ushort* array;
    } sem_val;
    struct sembuf semPtr;
    
    
    
    //Initialize random seed
    //srand(time(NULL));
    /* This gives random distribution for which resources to choose */
    //uniform_real_distribution<int> resource_dist (0, 5);    // this gives range [0, 5)
    /* This gives random distribution for number of loops each process run for */
    //uniform_real_distribution<int> loop_dist (5, 16);       // this gives range [0, 5)
    
    //Create semaphore
    semKey = ftok("./", 's');
    semID = semget(semKey, 1, IPC_CREAT | 0600);
    if (semID == -1) {
        perror ("semID fails");
        exit(1);
    }
    
    /* Initialize the first (and single) semaphore to '1' */
    sem_val.val = 1;
    rc = semctl(semID, 0, SETVAL, sem_val);
    if (rc == -1) {
    switch (errno) {
    case EACCES: cout <<"access";
    case EINVAL: cout <<"index";
    case ERANGE: cout <<"range";
    };
        
        cout << endl;
        perror ("semctl fails");
        exit(1);
    }
    
    //Create shared memory
    ShmKey = ftok("./", 'u');
    ShmID = shmget (ShmKey, sizeof(struct Memory), IPC_CREAT | 06666);
    //If fails to get shared memory id
    if (ShmID < 0) {
        perror ("shmget");
        exit(1);
    }

    mPtr = (struct Memory *) shmat (ShmID, NULL, 0);
    
    //Initialize struct
    for (int i = 0; i < RESOURCES; i++) {
        mPtr->var[i] = i*10;
    }
    
    cout << "------------------------------" << endl; //space
    for (int i = 0; i < RESOURCES; i++) {
        printf("%d: %f, ",i, mPtr->var[i]);
    }
    cout << "\n------------------------------" << endl; //space

    //Create 10 child process
    for (int childIndex = 0; childIndex < PROCESS; childIndex++) {
        childPid[childIndex] = fork();
        if (childPid[childIndex] < 0) {
            perror ("fork fails");
            exit(1);
        }
        
        //Inside child process
        if (childPid[childIndex] == 0) {
            //Link to shared memory
            mPtr = (struct Memory *) shmat (ShmID, NULL, 0);
            //Loop
            for (int loop = 0; loop < (childIndex+1)*LOOP_NUMBER; loop++) {
                /* Use mt19937 generator to create random values of beta and chosen_resource */
                mt19937 generator(chrono::high_resolution_clock::now().time_since_epoch().count());
                uniform_real_distribution<float> beta_dist (-5, 5);
                float random = beta_dist(generator); /* random value obtained from generator */
                float beta = random / 10;
                int chosen_resource = abs((int)random) % 4 ;
                
                /* Adding beta operation */
                cout << sem_lock(chosen_resource, semID, getpid());
                cout << endl;
                printf("%d     locked semaphore\n", getpid());
                printf("%d-----Adding %f to variable %d\n", getpid(), beta, chosen_resource);
                mPtr->var[chosen_resource] += beta;
                printf("%d     is unlocking semaphore\n", getpid());
                sem_unlock(chosen_resource, semID, getpid());
            }
            exit(0);
        }
	else if (childPid > 0) {
		int status = 0;
	   	pid_t pid;
	    	int count = PROCESS;
	    	while (count > 0) {
	    	   pid = wait(&status);
	    	   printf("Child with PID %ld exited.\n", (long)pid);
	    	    --count;
		} 
   	 }
    }
    
    //Get status of children processes.
    //int status = 0;
    //pid_t pid;
    //int count = PROCESS;
    //while (count > 0) {
    //    pid = wait(&status);
    //    printf("Child with PID %ld exited.\n", (long)pid);
    //    --count;
    //} */
    
    //Get results
    cout << "------------------------------" << endl; //space
    //Print out results
    for (int i = 0; i < RESOURCES; i++) {
        printf("%d: %f, ",i, mPtr->var[i]);
    }
    cout << "\n------------------------------" << endl; //space
    
    //Detach from shared memory
    shmdt((void *) mPtr);
    //Delete shared memory
    shmctl(ShmID, IPC_RMID, NULL);
    return 0;
    
    //Remove semaphore
    semID = semget(semKey, 1, 0);
    if(semctl(semID, 0, IPC_RMID) < 0) {
        perror ("Fail to remove semaphore");
        exit(1);
    }
    exit (0);
}

0 个答案:

没有答案