SystemV IPC设施:它们具有未定义和不可预测的行为

时间:2017-02-13 14:50:31

标签: c linux unix operating-system ipc

今天我参加了OS课程考试,我认为我没有成功。 作业是这样的:

  

编写一个实现读者和经典机制的程序   作家(优先于读者)。使用以这种方式定义的结构   struct { unsigned long read_count; unsigned long value};作为共享内存。   主要必须创建n个读取器进程和m个写入器进程,其中n和m   作为参数传递给main。   读者将打印value,而作家将读取它并将其递增1。   要保证同步和互斥,请使用两个信号量(mutex   和rw_mutex)。

我的教授编写了SEM_ *函数,以简化我们的工作

这就是我的做法(D用于调试目的)。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <pthread.h>
#include <string.h>
#include <sys/sem.h>
#include <sys/shm.h>


#define SHM_KEY (key_t) 1234        
#define MUTEX_KEY (key_t) 5678      
#define RW_MUTEX_KEY (key_t) 91011  
#define SIZE sizeof(SharedMemory)   
#define MAX_PROCESSES 1000          
#define D                           


typedef struct {
    unsigned long read_count;
    unsigned long value;
} SharedMemory;


int shm_id, mutex, rw_mutex;
SharedMemory *shm;
void *mem_addr;


void reader(void);
void writer(void);


union semun {
    int val;
    struct semid_ds *buf;
    unsigned short *array;
};


int SEM_SET(int sem_id, int sem_num, int sem_val)
{
    union semun sem_union;
    sem_union.val = sem_val;
    if (semctl(sem_id, sem_num, SETVAL, sem_union) == -1) {
        return -1;
    }
    return 0;
}


void SEM_DEL(int sem_id, int sem_num)
{
    union semun sem_union;
    if (semctl(sem_id, sem_num, IPC_RMID, sem_union) == -1) {
        perror("Failed to delete semaphore");
    }
}


int SEM_P(int sem_id, int sem_num)
{
    struct sembuf sem_b;
    sem_b.sem_num = sem_num;
    sem_b.sem_op = -1;
    sem_b.sem_flg = SEM_UNDO;
    if (semop(sem_id, &sem_b, 1) == -1) {
        return -1;
    }
    return 0;
}


int SEM_V(int sem_id, int sem_num)
{
    struct sembuf sem_b;
    sem_b.sem_num = sem_num;
    sem_b.sem_op = 1;
    sem_b.sem_flg = SEM_UNDO;
    if (semop(sem_id, &sem_b, 1) == -1) {
        return -1;
    }
    return 0;
}


int main(int argc, char *argv[])
{
    if (argc < 3) {
        printf("Usage: main <readers> <writers>\n");
        exit(EXIT_SUCCESS);
    }

    if (argc == 4) {
        #define D printf("%d\n", __LINE__);
    }

    int val, i, stat_loc;
    int readers = atoi(argv[1]), writers = atoi(argv[2]);
    int n_processes = readers + writers;
    pid_t temp_pid, children[n_processes];

    D;
    shm_id = shmget(SHM_KEY, SIZE, IPC_CREAT | 0666);
    if (shm_id == -1) {
        perror("Error creating the shared memory");
        exit(EXIT_FAILURE);
    }
    D;

    D;
    mutex = semget(MUTEX_KEY, 1, IPC_CREAT | 0666);
    if (mutex == -1) {
        perror("Error creating the mutex semaphore");
        exit(EXIT_FAILURE);
    }
    D;

    D;
    rw_mutex = semget(MUTEX_KEY, 1, IPC_CREAT | 0666);
    if (rw_mutex == -1) {
        perror("Error creating the rw_mutex semaphore");
        exit(EXIT_FAILURE);
    }
    D;

    D;
    mem_addr = shmat(shm_id, (void *) 0, 0);
    if (mem_addr == (void *) -1) {
        perror("Error attaching to the memory");
        exit(EXIT_FAILURE);
    }
    D;

    D;
    shm = (SharedMemory *) mem_addr;
    D;

    D;
    val = SEM_SET(mutex, 0, 1);
    if (val == -1) {
        perror("Error initializing the mutex semaphore");
        exit(EXIT_FAILURE);
    }
    D;

    D;
    val = SEM_SET(rw_mutex, 0, 1);
    if (val == -1) {
        perror("Error initializing the rw_mutex semaphore");
        exit(EXIT_FAILURE);
    }
    D;

    D;
    for (i = 0; i < readers; i++) {
        temp_pid = fork();
        if (temp_pid == -1) {
            perror("Error creating the process");
            exit(EXIT_FAILURE);
        }
        else if (temp_pid != 0) {
            children[i] = temp_pid;
        }
        else {
            reader();
        }
    }
    D;

    D;
    for (; i < n_processes; i++) {
        temp_pid = fork();
        if (temp_pid != 0) {
            children[i] = temp_pid;
        }
        else {
            reader();
        }
    }
    D;

    D;
    for (i = 0; i < n_processes; i++) {
        temp_pid = waitpid(children[i], &stat_loc, 0);
        if (WIFEXITED(stat_loc)) {
            printf("Process with PID %d exited with exit status %d.\n", temp_pid, WEXITSTATUS(stat_loc));
        }
        else {
            printf("Process with PID %d exited abnormally.\n", temp_pid);
        }
    }
    D;

    D;
    val = shmdt(mem_addr);
    if (val == -1) {
        perror("Error detaching from memory");
        exit(EXIT_FAILURE);
    }
    D;

    D;
    val = shmctl(shm_id, IPC_RMID, 0);
    if (val == -1) {
        perror("Error erasing memory");
        exit(EXIT_FAILURE);
    }
    D;

    SEM_DEL(mutex, 0);
    SEM_DEL(rw_mutex, 0);

    printf("Resources unallocated successfully.\n");
    printf("Finished.\n");

    exit(EXIT_SUCCESS);
}


void reader(void)
{
    int val;
    D;
    val = SEM_P(mutex, 0);
    if (val == -1) {
        perror("P() failed");
        exit(EXIT_FAILURE);
    }
    D;
    shm->read_count += 1;
    D;
    if (shm->read_count == 1) {
        D;
        SEM_P(rw_mutex, 0);
        D;
    }
    D;
    printf("Value (PID %d) = %lu.\n", getpid(), shm->value);
    D;
    shm->read_count -= 1;
    D;
    if (shm->read_count == 0) {
        D;
        SEM_V(rw_mutex, 0);
        D;
    }
    D;
    val = SEM_V(mutex, 0);
    if (val == -1) {
        perror("V() failed");
        exit(EXIT_FAILURE);
    }
    D;
}


void writer(void)
{
    unsigned long x;
    int val;

    D;
    val = SEM_P(mutex, 0);
    if (val == -1) {
        perror("P() failed");
        exit(EXIT_FAILURE);
    }
    D;
    SEM_P(rw_mutex, 0);

    x = shm->value;
    x += 1;
    shm->value = x;
    D;
    SEM_V(rw_mutex, 0);
    D;
    val = SEM_V(mutex, 0);
    if (val == -1) {
        perror("V() failed");
        exit(EXIT_FAILURE);
    }
    D;
}

使用该程序运行的示例给出了以下错误

riccardo@riccardo-PC:~/Documents/Programming/OS/Collection/Compito$ ./main 1 1 e106
112
114
120
122
128
130
136
138
140
142
148
150
156
158
172
174
227
233
235
237
184
186
227

或(没有第四个参数)

riccardo@riccardo-PC:~/Documents/Programming/OS/Collection/Compito$ ./main 1 1 
106
112
114
120
122
128
130
136
138
140
142
148
150
156
158
172
174
227
233
235
241
Value (PID 10805) = 0.
243
184
245
186
251
257
172
174
227
233
235
241
Value (PID 10806) = 0.
243
245
251
257
184
186
Process with PID -1 exited abnormally.
Process with PID -1 exited abnormally.
184
196
186
198
204
206
212
Failed to delete semaphore: Invalid argument
Resources unallocated successfully.
Finished.
227
P() failed: Invalid argument
Process with PID 10807 exited with exit status 1.
Process with PID -1 exited with exit status 1.
196
198
204
206
212
Failed to delete semaphore: Invalid argument
Failed to delete semaphore: Invalid argument
Resources unallocated successfully.
Finished.
Process with PID 10805 exited with exit status 0.
Process with PID 10806 exited with exit status 0.
196
198
204
206
Error erasing memory: Invalid argument
你可以帮我弄清楚出了什么问题。似乎我们进入reader()函数,它以某种方式卡住了。 感谢。

0 个答案:

没有答案