Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Przerwanie funkcji sleep() i wykonanie pętli n razy

Ostatnio zmodyfikowano 2020-10-01 18:14
Autor Wiadomość
gonskabalbinka
Temat założony przez niniejszego użytkownika
Przerwanie funkcji sleep() i wykonanie pętli n razy
» 2020-09-22 20:12:20
Witam
Mam do poprawienia fragment kodu, który ma wykonać się zadaną ilość razy. Poniższy kod to kod sprawdzarki serwera i nie może być zmieniony.
C/C++
#include <criterion/criterion.h>
#include <stdio.h>
#include <stdatomic.h>
#include <unistd.h>

void execute( void( * )(), int );

static atomic_int counter;

void thread() {
    fputs( ".", stdout );
    sleep( 1 /* second */ );
    counter += 1;
}

Test( the_multiply_function, should_pass_all_the_tests_provided ) {
    execute( & thread, 20 );
    if( counter != 20 ) {
        cr_assert_fail( "Action was executed %d times instead of %d times", counter, 20 );
    } else {
        cr_assert( 1 );
    }
}

Funkcja execute, pobiera wskaźnik na funkcję w tym przypadku thread. Funkcja thread() wypisuje "." na standardowe wyjście. Funkcja musi wykonać się zadaną ilość razy w określonym czasie. Użycie funkcji sleep() wydłuża ten czas i serwer wyrzuca błąd.
Poniższy kod to moja próba naprawienia tego błędu.

C/C++
#include <signal.h>
#include <sys/types.h>
void execute( void( * action )(), int nTimes ) {
    for( int i = 0; i < nTimes; i += 1 ) {
        action();
        raise( SIGINT );
    }
}
Próbuję wysłać sygnał do funkcji thread(), tak żeby przerwać funkcję sleep(), ale nie daje to rezultatu. Czy ktoś mógłby powiedzieć, gdzie jest błąd?
P-177560
pekfos
» 2020-09-22 23:27:20
Uruchom N równoległych instancji tej funkcji. counter jest atomowe nie bez powodu.

Próbuję wysłać sygnał do funkcji thread(), tak żeby przerwać funkcję sleep(), ale nie daje to rezultatu.
Próbujesz przerwać bieżącą operację przyszłą operacją. To nie ma prawa dać rezultatu.
P-177561
gonskabalbinka
Temat założony przez niniejszego użytkownika
OMP Paralell for
» 2020-09-24 19:07:22
Próbowałem też tego triku, ale to też nie działa
C/C++
#include <omp.h>
#pragma omp parallel
void execute( void( * action )(), int nTimes ) {
    #pragma omp for schedule(dynamic, 100)
    for( int i = 0; i < nTimes; i += 1 ) {
        action();
    }
}
P-177562
pekfos
» 2020-09-24 19:15:11
Nie używaj trików, tylko zwykłych wątków. OpenMP nie musi działać - bez odpowiednich opcji kompilatora możesz równie dobrze pisać komentarze, a z tego co rozumiem, nie Ty odpowiadasz tu za kompilację kodu.
P-177563
gonskabalbinka
Temat założony przez niniejszego użytkownika
Wywołuję funkcję tworzącą wątki.
» 2020-09-24 22:20:11
Na wyjściu program wypisuje 20 znaków "." czyli tak jak wynika z przykładowego testu, ale dostaję komunikat: Action was executed 0 times instead of 20 times. Plus dodatkowo na stderr "solution.c:5:27: warning: incompatible function pointer types passing 'void (*)()' to parameter of type 'void *(*)(void *)' [-Wincompatible-function-pointer-types]
    pthread_create(&tid,0,action,0);
                          ^~~~~~
/usr/include/pthread.h:236:15: note: passing argument to parameter '__start_routine' here
                           void *(*__start_routine) (void *),
                                   ^
1 warning generated."

Mój kod poniżej:
C/C++
#include <pthread.h>
void execute( void( * action )(), int nTimes ) {
    for( int i = 0; i < nTimes; i += 1 ) {
        unsigned long tid;
        pthread_create( & tid, 0, action, 0 );
    }
}
Chyba sam sobie z tym nie poradzę.
P-177564
pekfos
» 2020-09-24 22:32:43
Wykonanie akcji jest rejestrowane po jednosekundowym opóźnieniu, więc nie możesz po prostu odpalić wątków i o nich zapomnieć. Najpierw utwórz N wątków i zapisz uchwyty do nich, potem w drugiej pętli odczekaj na zakończenie każdego z nich (pthread_join()).

Plus dodatkowo na stderr "solution.c:5:27: warning: incompatible function pointer types passing 'void (*)()' to parameter of type 'void *(*)(void *)' [-Wincompatible-function-pointer-types]
Funkcja wątku musi mieć formę void* f(void*), a nie byle jaką. Argument void* to dowolna wartość wskaźnikowa którą możesz przemycić do wątku przy jego tworzeniu (ostatni argument pthread_create()), możesz tak przekazać wskaźnik na action i wewnątrz wątku wywołać tą funkcję.
P-177565
gonskabalbinka
Temat założony przez niniejszego użytkownika
Dzięki za odpowiedzi
» 2020-09-24 22:39:01
Wezmę się za to już jutro, bo dzisiaj już nie mam siły
P-177566
gonskabalbinka
Temat założony przez niniejszego użytkownika
Problem rozwiązany
» 2020-10-01 18:14:03
Dzięki za odpowiedzi.
P-177575
« 1 »
  Strona 1 z 1