чтение и запись int из / в разделяемую память в c - PullRequest
0 голосов
/ 30 марта 2020

Я пытаюсь создать программу, в которой поток записывает целое число в общую память, а затем другой поток читает и печатает это целое число. проблема, с которой я сталкиваюсь, заключается в том, что второй поток продолжает читать целое число как -1. Вот мой код:

#include <stdio.h> 
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h> 
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
#include <string.h>


struct args {
    void* memptr;
    sem_t* semptr;
};

void *p1(void *vargp) 
{
    void* memory = ((struct args*)vargp)->memptr;
    sem_t* semaphore = ((struct args*)vargp)->semptr;
    //sem_wait(semaphore);
    //sleep(0.5);
    for(int i=0; i<=10; i++)
    {
        if (!sem_wait(semaphore)) {
            printf("got in if p1\n");
            sprintf(memory, "%d", i);
            sem_post(semaphore);
            sleep(1);
        }
    }
    if (!sem_wait(semaphore)) {
        sprintf(memory, "%d", 0);
        sem_post(semaphore);
        sleep(1);
    }
    sleep(0.1);
}

void *p2(void *vargp) 
{
    void* memory = ((struct args*)vargp)->memptr;
    sem_t* semaphore = ((struct args*)vargp)->semptr;
    sleep(0.1);
    while(1)
    {
        if (!sem_wait(semaphore)) {
            printf("got in if p2\n");
            if((int)memory == 0){
                break;
            }
            printf("%d\n", (int)memory);
            sem_post(semaphore);
            sleep(1);
        }
    }
} 

const int ByteSize = 4;
const char* SharedName = "memNameTest";
const char* SemaphoreName = "semNameTest";


int main() 
{   
    int fd = shm_open(SharedName, O_RDWR, 0644);
    ftruncate(fd, ByteSize);
    void* memptr = mmap(0, ByteSize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    sem_t* semptr = sem_open(SemaphoreName, O_CREAT, 0644, 0);
    sem_post(semptr);
    struct args *Share = (struct args *)malloc(sizeof(struct args));
    Share->memptr = memptr;
    Share->semptr = semptr;

    pthread_t thread1, thread2; 
    printf("Before Thread\n"); 
    pthread_create(&thread1, NULL, p1, (void*)Share);
    pthread_create(&thread2, NULL, p2, (void*)Share);
    pthread_join(thread1, NULL);
    pthread_join(thread2, NULL);
    printf("After Thread\n");



    munmap(memptr, ByteSize);
    close(fd);
    sem_close(semptr);
    unlink(SharedName);
    return 0;
    exit(0); 
}

Я пытался изменить (int)memory на *((int*)memory), но это привело к ошибке сегментации.

(редактировать), как я и предлагал, я попробовал это в одном многопоточная программа и заставила ее работать следующим образом:

#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h> 
#include <unistd.h>
#include <string.h>

int main()
{

    /* the size (in bytes) of shared memory object */
    const int SIZE = 4;
    /* name of the shared memory object */
    const char* SharedName = "memoryInt";
    /* create the shared memory object */
    int shm_fd = shm_open(SharedName, O_CREAT | O_RDWR, 0644);
    /* configure the size of the shared memory object */
    ftruncate(shm_fd, SIZE);
    /* memory map the shared memory object */
    void* memptr = mmap(0, SIZE, PROT_WRITE, MAP_SHARED, shm_fd, 0); 

    for(int i=1; i<=10; i++){
        /* write to the shared memory object */
        //sprintf(memptr, "%d", i);
        memcpy(memptr, &i, sizeof(int));
        printf("%d\n", *((int*)memptr));
        sleep(1);
    }

    return 0;
}

, хотя это все еще не работает в многопоточной программе, поскольку я получаю ошибку сегментации. это вывод:

Before Thread
got in if p1
Segmentation fault

1 Ответ

0 голосов
/ 30 марта 2020

Сначала вы должны показать, что происходит на вашем терминале при компиляции программы. Во-вторых, функция sprintf имеет объявление:

sprintf(char *str, const char *format, ...);

Это означает, что p1 запишет нулевую завершенную строку символа. В вашем коде я не понимаю, почему вы используете пустой указатель memory вместо использования указателя символа в качестве описания. Вы должны проверить функцию чтения / записи, используя однопоточность перед применением к многопоточности.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...