Pthreads w forku

0

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);
} 
0
ElNino napisał(a):

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ć?

Przydałaby się ściana błędów i linijka - nie każdy ma środowisko z którego uruchomi Twój program :]

0
gcc `pkg-config --cflags --libs opencv` filtrowanie.cpp -o filtrowanie
filtrowanie.cpp: In function ‘int main(int, char**)’:
filtrowanie.cpp:51: error: ‘wczytaj’ was not declared in this scope
filtrowanie.cpp:52: error: ‘czb’ was not declared in this scope
filtrowanie.cpp:53: error: ‘negatyw’ was not declared in this scope
filtrowanie.cpp:54: error: ‘kolejka’ was not declared in this scope
filtrowanie.cpp:56: error: ‘Pthread_join’ was not declared in this scope
filtrowanie.cpp: In function ‘void* wczytaj(void*)’:
filtrowanie.cpp:70: error: ‘blokadaO’ was not declared in this scope
filtrowanie.cpp:70: error: ‘Pthread_mutex_lock’ was not declared in this scope
filtrowanie.cpp:71: error: ‘nazwa’ was not declared in this scope
filtrowanie.cpp:75: error: ‘filepath’ was not declared in this scope
filtrowanie.cpp:77: error: expected primary-expression before ‘void’
filtrowanie.cpp:80: error: ‘Pthread_mutex_unlock’ was not declared in this scope
filtrowanie.cpp:81: error: ‘czekaj’ was not declared in this scope
filtrowanie.cpp:82: error: ‘blokadaZ’ was not declared in this scope
filtrowanie.cpp:83: error: ‘zapis’ was not declared in this scope
filtrowanie.cpp: In function ‘void* czb(void*)’:
filtrowanie.cpp:94: error: ‘odczyt’ was not declared in this scope
filtrowanie.cpp:94: error: ‘Pthread_mutex_lock’ was not declared in this scope
filtrowanie.cpp:95: error: ‘nazwa’ was not declared in this scope
filtrowanie.cpp:96: error: ‘blokadaO’ was not declared in this scope
filtrowanie.cpp:96: error: ‘Pthread_mutex_unlock’ was not declared in this scope
filtrowanie.cpp:99: error: ‘start’ was not declared in this scope
filtrowanie.cpp:100: error: ‘end’ was not declared in this scope
filtrowanie.cpp:128: error: ‘czas’ was not declared in this scope
filtrowanie.cpp:131: error: ‘czekaj’ was not declared in this scope
filtrowanie.cpp:132: error: ‘blokadaZ’ was not declared in this scope
filtrowanie.cpp:136: error: ‘zapis’ was not declared in this scope
filtrowanie.cpp: In function ‘void* negatyw(void*)’:
filtrowanie.cpp:146: error: ‘blokadaO’ was not declared in this scope
filtrowanie.cpp:146: error: ‘Pthread_mutex_lock’ was not declared in this scope
filtrowanie.cpp:147: error: ‘nazwa’ was not declared in this scope
filtrowanie.cpp:148: error: ‘Pthread_mutex_unlock’ was not declared in this scope
filtrowanie.cpp:153: error: ‘start’ was not declared in this scope
filtrowanie.cpp:154: error: ‘end’ was not declared in this scope
filtrowanie.cpp:165: error: ‘czas’ was not declared in this scope
filtrowanie.cpp:168: error: ‘czekaj’ was not declared in this scope
filtrowanie.cpp:169: error: ‘blokadaZ’ was not declared in this scope
filtrowanie.cpp:172: error: ‘zapis’ was not declared in this scope
filtrowanie.cpp: In function ‘void* nadzorca(void*)’:
filtrowanie.cpp:182: error: ‘blokadaZ’ was not declared in this scope
filtrowanie.cpp:183: error: ‘czekaj’ was not declared in this scope
filtrowanie.cpp: In function ‘void zapis(char*)’:
filtrowanie.cpp:191: error: ‘img’ was not declared in this scope
filtrowanie.cpp:192: error: ‘info’ was not declared in this scope
filtrowanie.cpp:193: error: ‘file’ was not declared in this scope
filtrowanie.cpp:193: error: ‘filepath’ was not declared in this scope
filtrowanie.cpp:196: error: ‘map’ was not declared in this scope
 

Sypie się od tego kawałka

 default:
    {
      pthread_create(&glowny, NULL, wczytaj, NULL);

Wyglada to tak jakbym srednik gdzies zgubil albo nie zadeklarowal typu zmiennych. No ale wszystko jest a nie działa.

A forka i watkow uzywam bo taka jest tresc tego zadania ;)

0

Hmm... może to głupi pomysł ale pierwsza rzecz jaka mi przyszła do głowy to żeby skopiować main() na koniec pliku.

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