Witam,
Piszę program który ma przy pomocy wątków filtrować równolegle zadany obrazek, po czym wrzucać go do pamięci zmapowanej. Dodatkowo odpalony za pomocą forka proces potomny ma wyswietlac caly czas te obrazki.
Problem w tym ze przy kompilacji (komendą gcc pkg-config --cflags --libs opencv
program.cpp -o program) od miejsca gdzie startuje 1 wątek po default forka kompilator wyrzuca mi ścianę błędów że nic nie zostało zdefiniowane. Czy da to się jakoś zmienić?
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <signal.h>
#include <fcntl.h>
#include <time.h>
#include <pthread.h>
#include <cv.h>
#include <highgui.h>
int main(int argc, char **argv)
{
pthread_t glowny, filtr1, filtr2, nadzorca;
pthread_mutex_t blokadaO = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t blokadaZ = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t czekaj = PTHREAD_COND_INITIALIZER;
int pid;
char nazwa[20];
int file,img;
void *map;
struct stat info;
clock_t start,end;
float czas;
char filepath[32] = "/tmp/mmapped-XXXXXX";
mkstemp(filepath);
file = open(filepath, O_EXCL | O_RDWR);
fstat(file,&info);
map = mmap(NULL, info.st_size, PROT_READ, MAP_PRIVATE,file, 0);
close(file);
switch(pid=fork())
{
case -1:
{
perror("Blad tworzenia potomka\n");
}
case 0:
{
execlp("display", "display", "-update", "1", "-delay", argv[1], filepath,NULL);
}
default:
{
pthread_create(&glowny, NULL, wczytaj, NULL);
pthread_create(&filtr1, NULL, czb, NULL);
pthread_create(&filtr2, NULL, negatyw, NULL);
pthread_create(&nadzorca, NULL, kolejka, NULL);
Pthread_join(glowny, NULL);
Pthread_join(filtr1, NULL);
Pthread_join(filtr2, NULL);
Pthread_join(nadzorca, NULL);
}
}
exit(0);
}
void* wczytaj(void *arg)
{
for(;;)
{
printf("Podaj nazwe pliku (wpisanie 'q' zamknie program): ");
Pthread_mutex_lock(&blokadaO);
scanf("%s", nazwa);
if (nazwa[0]=='q')
{
char remove[20]= "rm ";
strcat(remove,filepath);
system(remove);
pthread_exit();
break;
}
Pthread_mutex_unlock(&blokadaO);
pthread_cond_signal(&czekaj);
Pthread_mutex_lock(&blokadaZ);
zapis(nazwa);
Pthread_mutex_unlock(&blokadaZ);
printf("Wczytano!\n");
}
return(NULL);
}
void* czb(void *arg)
{
for(;;)
{
Pthread_mutex_lock(&odczyt.blokadaO);
IplImage *src = cvLoadImage(nazwa);
Pthread_mutex_unlock(&blokadaO);
IplImage *dst;
start=0;
end=0;
start=clock();
int width = src->width;
int height = src->height;
int depth = src->depth;
int nchannels = src->nChannels;
int i, j;
const int size = 3;
int arr[] = { -1, -1, -1,
-1, 8, -1,
-1, -1, -1 };
dst = cvCreateImage( cvSize( width, height ), depth, nchannels );
CvMat* kernel = cvCreateMat(3, 3,CV_32FC1);
for(i =0; i<size; ++i)
{
for(j=0; j<size; ++j)
{
cvSet2D( kernel, i, j, cvRealScalar(arr[i*size+j]));
}
}
cvFilter2D(src, dst, kernel, cvPoint(-1,-1));
end=clock();
czas=end-start;
printf("Wykonany filtr zmiany kolorow. Czas: %d\n",czas);
pthread_cond_signal( &czekaj );
Pthread_mutex_lock(&blokadaZ);
cvSaveImage("tmp", dst );
cvReleaseImage( &src );
cvReleaseImage( &dst );
zapis("tmp");
Pthread_mutex_unlock(&blokadaZ);
}
return(NULL);
}
void* negatyw(void *arg)
{
for(;;)
{
Pthread_mutex_lock(&blokadaO);
IplImage *src = cvLoadImage(nazwa);
Pthread_mutex_unlock(&blokadaO);
IplImage *image = cvCreateImage(cvGetSize(src), src->depth, src->nChannels);
cvCopy(src, image, NULL);
start=0;
end=0;
start=clock();
int s,w,k;
for(s=0; s<image->width; s++)
for(w=0; w<image->height;w++)
for(k=0; k<image->nChannels; k++)
image->imageData[ w * image->widthStep + s*image->nChannels + k ]=
255-image->imageData[ w * image->widthStep + s*image->nChannels + k ];
end=clock();
czas=end-start;
printf("Wykonana negacja Czas: %d\n",czas);
pthread_cond_signal( &czekaj );
Pthread_mutex_lock(&blokadaZ);
cvSaveImage("tmp", image);
cvReleaseImage( &image );
zapis("tmp");
Pthread_mutex_unlock(&blokadaZ);
}
return(NULL);
}
void* nadzorca(void *arg)
{
for(;;)
{
pthread_mutex_lock(&blokadaZ);
pthread_cond_wait( &czekaj, &blokadaZ);
pthread_mutex_unlock(&blokadaZ);
}
return(NULL);
}
void zapis(char &name[20])
{
img=open(name, O_RDONLY);
fstat(img,&info);
file = open(filepath, O_EXCL | O_RDWR );
ftruncate(file, info.st_size);
fstat(file,&info);
map = mmap(NULL, info.st_size, PROT_WRITE | PROT_READ, MAP_SHARED, file, 0);
close(file);
read(img, map, info.st_size);
close(img);
}