在C中使用共享内存程序麻烦

发布于 2025-02-12 00:50:53 字数 2587 浏览 0 评论 0原文

我有一个分配,该分配包括制作具有父进程的共享内存的程序,该程序从.txt读取并将其内容添加到缓冲区中(这是共享内存),以及两个切换的子进程缓冲区的内容,并将它们输出两个文件。一个孩子将它们输出大写,另一个孩子在小写中输出。我已经实现了信号量和共享内存,但是我的输出文件变为空。顺便说一句,该程序是在Linux上运行的;我为契约使用虚拟机。我想获得一些关于我做得不正确的指导。

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>

int main() {
    FILE *archivo, *salida1, *salida2;
    int i = 0;
    int j, k;
    char actual;
    
    key_t claveMC = ftok("UCAB.txt", 5);
    int shmid = shmget(claveMC, 512, 0777 | IPC_CREAT);
    char *buffer = (char*)shmat(shmid, NULL, 0);
    
    key_t claveSem = ftok("UCAB.txt", 7);
    int idsem = semget(claveSem, 1, IPC_CREAT | 0100);
    struct sembuf valores;
    valores.sem_num = 0;
    valores.sem_flg = 0;
    semctl(idsem, 0, SETVAL, 1);
        
    archivo = fopen("UCAB.txt", "r");
    
    int id = fork();
    int id2;

    if (id > 0) {
        printf("P: %d", id);
        id2 = fork();
        if (id2 > 0) {
            while (((actual = getc(archivo)) != EOF) && (i < 512)) {
                valores.sem_op = -1;
                semop(idsem, &valores, 1);
                buffer[i] = actual;
                valores.sem_op = 1;
                semop(idsem, &valores, 1);
                i++;
            }

            valores.sem_op = -1;
            semop(idsem, &valores, 1);
            printf("%s", buffer);
            valores.sem_op = 1;
            semop(idsem, &valores, 1);
            fclose(archivo);
            printf("\nPadre con id: %d", id2);
        }
        else {
            printf("H2: %d", id);
            salida2 = fopen("minusculas.txt", "w");

            for (j = 0; j < i; j++) {
                valores.sem_op = -1;
                semop(idsem, &valores, 1);
                putc(tolower(buffer[j]), salida2);
                valores.sem_op = 1;
                semop(idsem, &valores, 1);
            }

            printf("\nHijo 2 con id: %d", id2);
            fclose(salida2);
        }
    }
    else {
        //hijo1
        printf("H1: %d", id);
        salida1 = fopen("MAYUSCULAS.txt", "w");

        for (k = 0; k < i; k++) {
            valores.sem_op = -1;
            semop(idsem, &valores, 1);
            putc(toupper(buffer[k]), salida1);
            valores.sem_op = 1;
            semop(idsem, &valores, 1);
        }

        printf("\nHijo 1 con id: %d", id);
        fclose(salida1);
    }

    shmctl(shmid, IPC_RMID, NULL);

    return 0;
}

I have an assignment that consists of making a program with shared memory that has a parent process, which reads from a .txt and adds its contents to a buffer (this is the shared memory), and two child processes that switch the case of the contents of the buffer, and output them in two files. One child outputs them in uppercase and the other one in lowercase. I've implemented semaphores and shared memory, but my output files turn out empty. By the way, the program is run on Linux; I use a virtual machine for the deed. I'd like to get some guidance as to what I'm not doing correctly.

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>

int main() {
    FILE *archivo, *salida1, *salida2;
    int i = 0;
    int j, k;
    char actual;
    
    key_t claveMC = ftok("UCAB.txt", 5);
    int shmid = shmget(claveMC, 512, 0777 | IPC_CREAT);
    char *buffer = (char*)shmat(shmid, NULL, 0);
    
    key_t claveSem = ftok("UCAB.txt", 7);
    int idsem = semget(claveSem, 1, IPC_CREAT | 0100);
    struct sembuf valores;
    valores.sem_num = 0;
    valores.sem_flg = 0;
    semctl(idsem, 0, SETVAL, 1);
        
    archivo = fopen("UCAB.txt", "r");
    
    int id = fork();
    int id2;

    if (id > 0) {
        printf("P: %d", id);
        id2 = fork();
        if (id2 > 0) {
            while (((actual = getc(archivo)) != EOF) && (i < 512)) {
                valores.sem_op = -1;
                semop(idsem, &valores, 1);
                buffer[i] = actual;
                valores.sem_op = 1;
                semop(idsem, &valores, 1);
                i++;
            }

            valores.sem_op = -1;
            semop(idsem, &valores, 1);
            printf("%s", buffer);
            valores.sem_op = 1;
            semop(idsem, &valores, 1);
            fclose(archivo);
            printf("\nPadre con id: %d", id2);
        }
        else {
            printf("H2: %d", id);
            salida2 = fopen("minusculas.txt", "w");

            for (j = 0; j < i; j++) {
                valores.sem_op = -1;
                semop(idsem, &valores, 1);
                putc(tolower(buffer[j]), salida2);
                valores.sem_op = 1;
                semop(idsem, &valores, 1);
            }

            printf("\nHijo 2 con id: %d", id2);
            fclose(salida2);
        }
    }
    else {
        //hijo1
        printf("H1: %d", id);
        salida1 = fopen("MAYUSCULAS.txt", "w");

        for (k = 0; k < i; k++) {
            valores.sem_op = -1;
            semop(idsem, &valores, 1);
            putc(toupper(buffer[k]), salida1);
            valores.sem_op = 1;
            semop(idsem, &valores, 1);
        }

        printf("\nHijo 1 con id: %d", id);
        fclose(salida1);
    }

    shmctl(shmid, IPC_RMID, NULL);

    return 0;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

感情洁癖 2025-02-19 00:50:53

孩子们将i字符写入他们的文件,但是i仅在孩子分叉后才在父母中递增,因此他们的i保持零。

The children write i characters to their file, but i is only incremented in the parent after the children have been forked, so their i remains zero.

篱下浅笙歌 2025-02-19 00:50:53

叉子之后,孩子是父母的克隆(有差异,例如pid)。但是父母和子女的地址空间不同。因此,父母的变量“ i”与任何一个孩子的变量“ i”不同。

After fork, the child is a clone of the parent (with differences, like pid). But the address spaces of the parent and child are different. So, the variable "i" of the parent is not the same as the variable "i" of either of the children.

水晶透心 2025-02-19 00:50:53
  1. sem的许可:0600
  2. 来自父进程:
  3. 使用wait()检查过程的返回值更优化的
  4. fopen(...,“ r”),您应该检查返回值,
  5. 您应该在使用后销毁SEM和SHM
  1. permission for sem: 0600
  2. From the parent process: fopen(...,"r")
  3. using wait() for checking process's return value will be more optimal
  4. you should check return value
  5. you should destroy sem and shm after use
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文