Forum » Programiranje » Niti - segmentation fault
Niti - segmentation fault
DubleG ::
/* sem_primer4.c */ #include <stdio.h> #include <stdlib.h> #include <sys/shm.h> #include <sys/sem.h> #include <errno.h> #include <sched.h> #include <pthread.h> #include <math.h> #include <sched.h> #include <string.h> pthread_mutex_t izpis = PTHREAD_MUTEX_INITIALIZER; pthread_t tid[4]; /* V skupnem pomnilniku imamo lahko tudi strukturo */ typedef struct { char zakljuci_proces; /* Uporabimo za sinhronizacijo da vemo, kdaj zaključiti proces */ char nizs[20]; /* Niz, v katerem bo ime najlepše */ }skupna_struktura; /* Posamezni proces neprestano piše ime svoje kandidatke v skupni pomnilnik */ /* Posameznemu procesu sedaj podamo še identifikator semaforja */ void *nit1(void *args) { int i=0; char niz[20]="Sneguljcica\0"; skupna_struktura* kazalec = (skupna_struktura*)args; while (!kazalec->zakljuci_proces) /* Proces teče, dokler preko skupnega pomnilnika ne */ { pthread_mutex_lock(&izpis); /* Vstopimo v kritični odsek */ for (i=0; i<= strlen(niz); i++) /* Pišemo znak za znak, da malo upočasnimo program*/ { kazalec->nizs[i]=niz[i]; sched_yield(); /* Za vsakim znakom prepustimo časovno rezino OS */ } pthread_mutex_unlock(&izpis); /* Izstopimo iz njega */ } } void *nit2(void *args) { int i=0; char niz[20]="Trnjulcica\0"; skupna_struktura* kazalec = (skupna_struktura*)args; while (!kazalec->zakljuci_proces) /* Proces teče, dokler preko skupnega pomnilnika ne */ { pthread_mutex_lock(&izpis); /* Vstopimo v kritični odsek */ for (i=0; i<= strlen(niz); i++) /* Pišemo znak za znak, da malo upočasnimo program*/ { kazalec->nizs[i]=niz[i]; sched_yield(); /* Za vsakim znakom prepustimo časovno rezino OS */ } pthread_mutex_unlock(&izpis); /* Izstopimo iz njega */ } } void *nit3(void *args) { int i=0; char niz[20]="Pepelka\0"; skupna_struktura* kazalec = (skupna_struktura*)args; while (!kazalec->zakljuci_proces) /* Proces teče, dokler preko skupnega pomnilnika ne */ { pthread_mutex_lock(&izpis); /* Vstopimo v kritični odsek */ for (i=0; i<= strlen(niz); i++) /* Pišemo znak za znak, da malo upočasnimo program*/ { kazalec->nizs[i]=niz[i]; sched_yield(); /* Za vsakim znakom prepustimo časovno rezino OS */ } pthread_mutex_unlock(&izpis); /* Izstopimo iz njega */ } } void *nit4(void *args) { int i=0; char niz[20]="Rdeča kapica\0"; skupna_struktura* kazalec = (skupna_struktura*)args; while (!kazalec->zakljuci_proces) /* Proces teče, dokler preko skupnega pomnilnika ne */ { pthread_mutex_lock(&izpis); /* Vstopimo v kritični odsek */ for (i=0; i<= strlen(niz); i++) /* Pišemo znak za znak, da malo upočasnimo program*/ { kazalec->nizs[i]=niz[i]; sched_yield(); /* Za vsakim znakom prepustimo časovno rezino OS */ } pthread_mutex_unlock(&izpis); /* Izstopimo iz njega */ } } int main() { int shmid; /* Ustvarimo skupni pomnilnik viden le procesu in sinovom */ shmid=shmget(100,sizeof(skupna_struktura*),IPC_CREAT | 0600); if (shmid<0) { perror("Napaka"); return(errno); } printf("Racunalnik, racunalnik, v E-110 povej, katera najlepsa v dezeli je tej\n"); int cpid; int f; skupna_struktura* kazalec; /* Dobimo kazalec na skupni pomnilnik */ kazalec=(skupna_struktura*)shmat(shmid,(void *)0,0); kazalec->zakljuci_proces=0; pthread_create(&tid[0],0,nit1,(void*)kazalec); pthread_create(&tid[1],0,nit2,(void*)kazalec); pthread_create(&tid[2],0,nit3,(void*)kazalec); pthread_create(&tid[3],0,nit4,(void*)kazalec); shmdt(kazalec); /* V primeru, da je to oče, povečamo števec sinov za 1 */ /* Počakamo 1 s */ sleep(1); /* Nato pa izpišemo ime najlepše! */ pthread_mutex_lock(&izpis); printf("%s\n",kazalec->nizs); pthread_mutex_unlock(&izpis); /* Sinovom sporočimo, naj se zaključijo! */ kazalec->zakljuci_proces=1; /* Počakamo da se zaključijo */ shmdt(kazalec); shmctl(shmid,IPC_RMID,0); pthread_join(tid[0],0); pthread_join(tid[1],0); pthread_join(tid[2],0); pthread_join(tid[3],0); return 0; }
Naloga vrže Segmentation fault.
PS: po odgovoru bom nalogo zbrisal, da ne bom kaznovan za plagiatorstvo, ki ga nisem naredil, ker ne znam popravit neobvezne naloge
hvala
lp
GA-P55M-UD2,i5,12GB RAM,Radeon HD 4850,Crucial SSD 64GB,
WD 320GB,WD 5000GB,RevoDrive X2 100GB
WD 320GB,WD 5000GB,RevoDrive X2 100GB
- spremenil: DubleG ()
DubleG ::
ne razumem... :)
na vsak niz charov sem dodal \0 k prvotni besedi, pa ni pomagalo. Če si slučajno to mislil.
na vsak niz charov sem dodal \0 k prvotni besedi, pa ni pomagalo. Če si slučajno to mislil.
GA-P55M-UD2,i5,12GB RAM,Radeon HD 4850,Crucial SSD 64GB,
WD 320GB,WD 5000GB,RevoDrive X2 100GB
WD 320GB,WD 5000GB,RevoDrive X2 100GB
Zgodovina sprememb…
- spremenil: DubleG ()
BaRtMaN ::
Znakovna polja so vnaprej določene dolžine, nizi v poljih pa so velikokrat krajši. Zato se zapiše \0 na koncu uporabnih znakov.
Zdaj pa poglej, če so vsi nizi tako zapisani.
Zdaj pa poglej, če so vsi nizi tako zapisani.
DubleG ::
Pregledal vsako vrstico... Mislim, da zdaj to več ni problem.
GA-P55M-UD2,i5,12GB RAM,Radeon HD 4850,Crucial SSD 64GB,
WD 320GB,WD 5000GB,RevoDrive X2 100GB
WD 320GB,WD 5000GB,RevoDrive X2 100GB
DubleG ::
Nisem.
[New Thread 0x7ffff7052910 (LWP 9709)]
[New Thread 0x7ffff6851910 (LWP 9710)]
[New Thread 0x7ffff6050910 (LWP 9711)]
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7ffff6050910 (LWP 9711)]
0x0000000000400c89 in nit4 ()
[New Thread 0x7ffff7052910 (LWP 9709)]
[New Thread 0x7ffff6851910 (LWP 9710)]
[New Thread 0x7ffff6050910 (LWP 9711)]
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7ffff6050910 (LWP 9711)]
0x0000000000400c89 in nit4 ()
GA-P55M-UD2,i5,12GB RAM,Radeon HD 4850,Crucial SSD 64GB,
WD 320GB,WD 5000GB,RevoDrive X2 100GB
WD 320GB,WD 5000GB,RevoDrive X2 100GB
BigWhale ::
Daj prevedi z -g opcijo in ko bos dobil segfault napisi bt v debuggerju, da vidis kje stvar crkne.
DubleG ::
(gdb) backtrace
#0 0x0000000000400c89 in nit4 ()
#1 0x00007ffff7bc9a04 in start_thread () from /lib/libpthread.so.0
#2 0x00007ffff793380d in clone () from /lib/libc.so.6
#3 0x0000000000000000 in ?? ()
Ne vem no, meni to ne pove nič. Celotno funkcijo nit4 sem pregledal v detajle...
#0 0x0000000000400c89 in nit4 ()
#1 0x00007ffff7bc9a04 in start_thread () from /lib/libpthread.so.0
#2 0x00007ffff793380d in clone () from /lib/libc.so.6
#3 0x0000000000000000 in ?? ()
Ne vem no, meni to ne pove nič. Celotno funkcijo nit4 sem pregledal v detajle...
GA-P55M-UD2,i5,12GB RAM,Radeon HD 4850,Crucial SSD 64GB,
WD 320GB,WD 5000GB,RevoDrive X2 100GB
WD 320GB,WD 5000GB,RevoDrive X2 100GB
Zgodovina sprememb…
- spremenil: DubleG ()
BlueRunner ::
Tc, tc, tc...
Kakšna je razlika med sizeof(struct skupna_sktruktura) in sizeof(struct skupna_struktura*)?!?!?!
shmid=shmget(100,sizeof(skupna_struktura*),IPC_CREAT | 0600);
Kakšna je razlika med sizeof(struct skupna_sktruktura) in sizeof(struct skupna_struktura*)?!?!?!
BlueRunner ::
Druga napaka pa je ta, da kličeš shmdt takoj po pthread_create.
Tretja napaka pa je ta, da najprej (še enkrat) kličeš shmdt + shmctl še preden si počakal, da se niti zaključijo s pthread_join. Samo zato, ker si jim poslal signal, to še ne pomeni, da so že zaključile s pisanjem po shm.
Ko boš popravil vse tri napake, lahko pobrišeš tiste '\0', ker ne služijo ničemer.
Tretja napaka pa je ta, da najprej (še enkrat) kličeš shmdt + shmctl še preden si počakal, da se niti zaključijo s pthread_join. Samo zato, ker si jim poslal signal, to še ne pomeni, da so že zaključile s pisanjem po shm.
Ko boš popravil vse tri napake, lahko pobrišeš tiste '\0', ker ne služijo ničemer.
Zgodovina sprememb…
- spremenilo: BlueRunner ()
DubleG ::
HVALA!
GA-P55M-UD2,i5,12GB RAM,Radeon HD 4850,Crucial SSD 64GB,
WD 320GB,WD 5000GB,RevoDrive X2 100GB
WD 320GB,WD 5000GB,RevoDrive X2 100GB
Zgodovina sprememb…
- spremenil: DubleG ()
BigWhale ::
Meni gcc in VS pravi da je sizeof(skupna_struktura): 21.
To je prav ja. Ampak sizeof(... *) je pa 4 .. :)
BlueRunner ::
Meni gcc in VS pravi da je sizeof(skupna_struktura): 21.
To je prav ja. Ampak sizeof(... *) je pa 4 .. :)
Pri meni je pa 8
DubleG ::
Sem potem ugotovil sam, sizeof(skupna_struktura) vrne 21... Zdaj pa ni več valgrinda.
GA-P55M-UD2,i5,12GB RAM,Radeon HD 4850,Crucial SSD 64GB,
WD 320GB,WD 5000GB,RevoDrive X2 100GB
WD 320GB,WD 5000GB,RevoDrive X2 100GB
BigWhale ::
Meni gcc in VS pravi da je sizeof(skupna_struktura): 21.
To je prav ja. Ampak sizeof(... *) je pa 4 .. :)
Pri meni je pa 8
Ooooh, Mr. Big Shot! :P
BivšiUser2 ::
Če poženem kodo:
Če poženem
(-100,-100) je levo zgoraj, sega pa do (100,100)
Vhod:
4
-3 -2 3
-2 0 2
-3 -1 4
-1 -2 1
Izhod:
10
7
2
0
#include <stdio.h> #include <stdlib.h> int main() { int n; scanf("%d",&n); int **p = (int **) malloc(201*sizeof(int *)); for(int i=0;i<201;i++) { p[i]= (int *) calloc(201,sizeof(int)); } for(int i=0;i<n;i++) { int y,x,a; scanf("%d %d %d",&x,&y,&a); x+=100; y+=100; for(int i=y;i<y+a;i++) { for(int j=x;i<x+a;j++) { p[i][j]++; } } } for(int k=1;k<=n;k++) { int stevec=0; for(int i=0;i<201;i++) { for(int j=0;j<201;j++) { if(p[i][j]==k) stevec++; } } printf("%d\n",stevec); } return 0; }Dobim povsod seg. fault. (verjetno ga mešam pri calloc in malloc)
Če poženem
#include <stdio.h> int main(){ int n; scanf("%d", &n); int map[201][201]; for(int i = 0; i < 201; i++){ for(int j = 0; j < 201; j++){ map[i][j] = 0; } } for(int i = 0; i < n; i++){ int posY, posX, size; scanf("%d %d %d", &posY, &posX, &size); //sprintf("%d %d %d\n", posY+100, posX+100, size); posY += 100; posX += 100; for(int y = posY; y < size+posY; y++){ for(int x = posX; x < size+posX; x++){ map[y][x]++; } } } for(int k = 1; k <= n; k++){ int count = 0; for(int i = 0; i < 201; i++){ for(int j = 0; j < 201; j++){ if(k == map[i][j]){ count++; } } } printf("%d\n", count); } return 0; }dobim seg. fault pri dveh primerih. Povečam z 201 > 400 (dobim timeout (verjetno lappy ne zmore procesirat v 1 sekundi)).
(-100,-100) je levo zgoraj, sega pa do (100,100)
Vhod:
4
-3 -2 3
-2 0 2
-3 -1 4
-1 -2 1
Izhod:
10
7
2
0
SloTech - če nisi z nami, si persona non grata.
al_z ::
Vsakemu malloc (calloc) mora slediti free pred zaključkom programa, drugače se lahko začnejo dogajati resne napake v pomnilniku. C nima garbage collector-ja!
Brane22 ::
A ne spuca OS vse ostalo od programa, ko ta zaključi ?
On a journey of life I chose a psycho path...
galu ::
@OP zakaj uporabljaš shmget ipd. funkcije, ki so namenjene deljenju pomnilnika med procesi? Ti delaš z nitmi, katerih fora je, da uporabljajo isto kopico, data in code segmente. Imajo celo dostop do sklada izven niti.
@Brane22
Ja, sprosti pomnilnik, da ga lahko uporabijo drugi procesi. Zato res ni potrebno neposredno pred zaključkom programa sprostiti pomnilnika, ker to stori OS.
@Brane22
Ja, sprosti pomnilnik, da ga lahko uporabijo drugi procesi. Zato res ni potrebno neposredno pred zaključkom programa sprostiti pomnilnika, ker to stori OS.
Tako to gre.
Vredno ogleda ...
Tema | Ogledi | Zadnje sporočilo | |
---|---|---|---|
Tema | Ogledi | Zadnje sporočilo | |
» | [C] Sinhronizacija procesovOddelek: Programiranje | 1138 (1011) | Cvenemir |
» | skupni pomnilnik © linuxOddelek: Programiranje | 2477 (2323) | Keki |
» | [C++] threading in random, dostop do ramaOddelek: Programiranje | 935 (828) | popec |
» | [C] Narascajoce sortiranje linearnega seznamaOddelek: Programiranje | 1856 (1745) | Jebiveter |
» | C problemčekOddelek: Programiranje | 1060 (863) | OwcA |