Linux, problem producenta-konsumenta, Naruszenie ochrony pamieci

0

Witam, mam do zrobienia program rozwiązujacy problem producent-konsument przy założeniu ze wątki konsumenta komunikuja sie z wątkami producenta za pomocą bufora jednoelementowego.
Program kompiluje (gcc -pthread -o program problem.c), ale gdy chce uruchomic program to mam bład "Naruszenie ochrony pamieci" i mam pytanie w jaki sposób moge to ominać?
Linuxa jakiego uzywam to Debian9. Oto cały kod programu:

#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <semaphore.h>

#define VALUE 10

int produkty;	/* tylko do odczytu dla producenta i konsumenta */

struct{ 	/* dane wspólne dla konsumenta i producenta */
    int bufor[VALUE];
    sem_t mutex, nempty, nstored;
    } shared;
	
void *producent(void *arg)
{
    int i;
    for(i = 0; i < produkty; i++){
        sem_wait(&shared.nempty);	/* oczekiwanie na min. jedno wolne miejsce w buforze */
       
        sem_wait(&shared.mutex);
        shared.bufor[i % VALUE] = i;	/* zapamiętanie wartości w cyklicznym buforze */
       
        sem_post(&shared.mutex);
        sem_post(&shared.nstored);		/* kolejny wpisany element */
    }
    return(0);
}

void *konsument(void *arg)
{
    int i;
    for(i = 0; i < produkty; i++){
        sem_wait(&shared.nempty);	/* oczekiwanie na min. jeden gotowy element w buforze */
       
        sem_wait(&shared.mutex);
        if(shared.bufor[i % VALUE] != i);
            printf("bufor[%d] = %d\n", i, shared.bufor[i % VALUE]);
        sem_post(&shared.mutex);
        sem_post(&shared.nempty);		/* kolejne wolne miejsce */
    }
    return(0);
}

int main(int argc, char **argv)
{
    pthread_t tid_producent, tid_konsument;

    if(argc != 2){
        //err_quit("usage: prodcons1 <#items>");
    }
    produkty = atoi(argv[1]);
/* utworzenie trzech semaforów */
    sem_init(&shared.mutex, 0, 1);
    sem_init(&shared.nempty, 0, VALUE);
    sem_init(&shared.nstored, 0, 0);
/* utworzenie jednego wątku producenta i jednego wątku konsumenta */
    //set_concurrency(2);
    pthread_create(&tid_producent, NULL, producent, NULL);
    pthread_create(&tid_konsument, NULL, konsument, NULL);
/* oczekiwanie na zakończenie obu wątków */
    pthread_join(tid_producent, NULL);
    pthread_join(tid_konsument, NULL);
/* usunięcie semaforów */
    sem_destroy(&shared.mutex);
    sem_destroy(&shared.nempty);
    sem_destroy(&shared.nstored);
    exit(0);
}
0

"Naruszenie ochrony pamieci" to pewnie SegFault (nigdy nie pracowałem na spolszczonej dystrybucji). Masz najpewniej błąd w kodzie, próbowałeś debuggować (gdb)?

0
    if(argc != 2){
        //err_quit("usage: prodcons1 <#items>");
    }
    produkty = atoi(argv[1]);

Nie kończysz przy nieodpowiedniej liczbie argumentów więc czytasz nieistniejące dane.

0

Brakowało mi biblioteki o której totalnie zapomniałem <stdlib.h> i sprawdzajac gdb dostałem takie cos:

Starting program: /home/nickname/Dokumenty/test 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Program received signal SIGSEGV, Segmentation fault.
__GI_____strtol_l_internal (nptr=0x0, endptr=endptr@entry=0x0, base=base@entry=10, 
    group=group@entry=0, loc=0x7ffff7bb7400 <_nl_global_locale>)
    at ../stdlib/strtol_l.c:293
293	../stdlib/strtol_l.c: Nie ma takiego pliku ani katalogu.
(gdb) bt
#0  __GI_____strtol_l_internal (nptr=0x0, endptr=endptr@entry=0x0, 
    base=base@entry=10, group=group@entry=0, loc=0x7ffff7bb7400 <_nl_global_locale>)
    at ../stdlib/strtol_l.c:293
#1  0x00007ffff7853c82 in __strtol (nptr=<optimized out>, endptr=endptr@entry=0x0, 
    base=base@entry=10) at ../stdlib/strtol.c:106
#2  0x00007ffff7851290 in atoi (nptr=<optimized out>) at atoi.c:27
#3  0x0000555555554ac9 in main ()

0

Problem raczej będzie taki jak sugeruje @Delor. Zmień warunek sprawdzania argumentów na:

if (argc < 2) {
    printf("usage: ....");
    exit(EXIT_FAILURE);
}

Również zbuduj swój program instruując gcc aby włączył symbole debugowe - opcja -d. Wtedy gdb więcej Ci powie, warto ustawić pułapkę w miejscu wywołania atoi() i zobaczyć co przekazujesz do tej funkcji.

0

Reszta uwag:
W treści zadania jest mowa o buforze jednoelementowym a nie o kolejce cyklicznej.
Nie potrzebujesz tylu mutexów.
Ilość produktów możesz przekazać do producenta. Unikniesz wtedy tej zmiennej globalnej. Tylko poinformuj konsumenta o braku danych/konieczności zakończenia wątku.

0

Dobra uporałem sie z tym programem, ogólnie go troche przebudowałem na potrzeby całkowitego przerobienia tego if'a ze sprawdzaniem argumentów i program działa poprawnie. Dzieki wszystkim za komentarze oraz za udzielone uwagi i rady.
temat do zamknięcia.

1 użytkowników online, w tym zalogowanych: 0, gości: 1