Pthreads w forku

EN
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 2
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ć?

Kopiuj
#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);
} 
HO
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 283
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 :]

EN
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 2
0
Kopiuj
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

Kopiuj
 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 ;)

HO
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 283
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.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.