Hitta felet (shared memory, mutex, thread)
Hej, har gjort ett program som är till för att lära mig själv trådar, shared memory och mutual exclusion. Tyvärr så finns det en bugg eller två jag inte kan hitta i min kod (förutom att jag förmodligen programmerat det hela som en nolla från början, men det hör inte hit).
Hade tänkt bygga upp det hela med hjälp av två trådar:
Tråd 1
Mutex lock
Skriver till shared memory buffer
om buffer full -> mutex unlock
vänta på tråd 2
Tråd 2
Mutex lock
Läs från shared memory och skriv ut
om hela buffern är läst -> mutex unlock
vänta på tråd 1
Det hela verkar funka som förväntat tills man kommer fram till den andra tråden, där man ska vänta på att tråd 1 ska ta över verksamheten igen(programmet fastnar i en oändlig loop(har förvisso satt en oändlig loop där den fastnar, men mutex är öppen och tråd1 bör ta över igen ganska omgående???)).
/* Compile with:
* cc Task6.c -o Task6 -pthread
*/
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <pthread.h>
#define SHMSIZE 128
//Shared memory specific part
char* addr = 0;
int i,j,k;
int var1, var2;
struct shmid_ds* shm_buf;
int shmid;
struct post* shmp;
//mutex
pthread_mutex_t mutex;
pthread_mutex_t mutex2;
pthread_cond_t w;
struct post
{
int character[10];
};
void*
thr_a (void* arg){ /* Thread A */
if(pthread_mutex_trylock(&mutex)!=0){
printf("Error or failed to lock thread");
}else{
printf("\nthr_a locked\n");
}
j=0;
while (var1++ < 100)
{
/* write to shmem */
shmp->character[j] = var1;
printf("wrote something to buffer\n");
if (j == 9){ // buffer is full
if(pthread_mutex_unlock(&mutex)!=0){
printf("Error or failed to open thread");
}else{
printf("\nThr_a open\n");
while(1);
}
}
j++;
}
shmdt(addr); //detatches the memory located at "addr" from the adress space of the calling program.
shmctl(shmid, IPC_RMID/*Marks the segment to be destroyed*/, shm_buf); //performs an operation specified by the 2nd argument (IPC_RMID)
pthread_exit(0);
}
void*
thr_b (void* arg){ /* Thread B */
if(pthread_mutex_trylock(&mutex2)!=0){
printf("Error or failed to lock thread");
}else{
printf("\nthr_b locked\n");
}
k=0;
while (var2 < 100)
{
/* read from shmem */
var2 = shmp->character[k];
printf("%d\n", var2);
if (k == 9){ // buffer is empty
if (pthread_mutex_unlock(&mutex2)!=0){
printf("Error or failed to open thread");
}else{
printf("\nthr_b open\n");
while(1);
}
}
k++;
}
shmdt(addr); //detatches the memory located at "addr" from the adress space of the calling program.
shmctl(shmid, IPC_RMID/*Marks the segment to be destroyed*/, shm_buf); //performs an operation specified by the 2nd argument (IPC_RMID)
pthread_exit(0);
}
void
main()
{
//mutex
pthread_mutex_init(&mutex,NULL);
pthread_mutex_init(&mutex2,NULL);
//shared memory
shmid = shmget(IPC_PRIVATE, SHMSIZE, IPC_CREAT | SHM_R | SHM_W ); // returns a identifier for the allocated memory segment.
shmp = (struct post*) shmat(shmid, addr, 0); // returns the address of the shared memory segment(of the shmid).
// Thread stuff
pthread_t tid_a;
pthread_t tid_b;
pthread_create(&tid_a, NULL, thr_a, NULL); // Create thread 1
pthread_create(&tid_b, NULL, thr_b, NULL); // Create thread 2
pthread_join(tid_a,NULL);
pthread_join(tid_b,NULL);
}