Добавил:
north memphis Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

practic2

.c
Скачиваний:
0
Добавлен:
17.07.2026
Размер:
5 Кб
Скачать
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <pthread.h>
#include <errno.h>

typedef struct {
    int signal;          //(SIGUSR1 or SIGRTMIN)
    int expected;        
    int mode;            // 0 = sync, 1 = async
} thread_params_t;


pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
int ready = 0;          
int done = 0;           
int received = 0;       


void async_handler(int sig, siginfo_t *info, void *context) {
    printf("Сигнал №%d получен, value %d\n",
           info->si_signo, info->si_value.sival_int);
    fflush(stdout);

    pthread_mutex_lock(&mutex);
    received++;
    pthread_cond_signal(&cond);
    pthread_mutex_unlock(&mutex);
}


void* receiver_thread(void *arg) {
    thread_params_t *params = (thread_params_t*) arg;
    int sig = params->signal;
    int expected = params->expected;
    int mode = params->mode;   // 0 = sync, 1 = async

    sigset_t mask;
    struct sigaction sa;

    sigemptyset(&mask);
    sigaddset(&mask, sig);
    pthread_sigmask(SIG_BLOCK, &mask, NULL);

    if (mode == 1) { 
        memset(&sa, 0, sizeof(sa));
        sa.sa_sigaction = async_handler;
        sa.sa_flags = SA_SIGINFO;
        sigemptyset(&sa.sa_mask);
        if (sigaction(sig, &sa, NULL) == -1) {
            perror("sigaction");
            return NULL;
        }
    }


    pthread_mutex_lock(&mutex);
    ready = 1;
    pthread_cond_signal(&cond);
    pthread_mutex_unlock(&mutex);


    pthread_mutex_lock(&mutex);
    while (!done) {
        pthread_cond_wait(&cond, &mutex);
    }
    pthread_mutex_unlock(&mutex);

    printf("# START...приемника *****\n");

    if (mode == 0) { 
        siginfo_t info;
        for (int i = 0; i < expected; i++) {
            int ret = sigwaitinfo(&mask, &info);
            if (ret == -1) {
                perror("sigwaitinfo");
                break;
            }
            printf("Сигнал №%d получен, value %d\n",
                   info.si_signo, info.si_value.sival_int);
        }
    } else { 
        pthread_sigmask(SIG_UNBLOCK, &mask, NULL);


        pthread_mutex_lock(&mutex);
        while (received < expected) {
            pthread_cond_wait(&cond, &mutex);
        }
        pthread_mutex_unlock(&mutex);
    }

    return NULL;
}

int main(int argc, char *argv[]) {
    if (argc != 3) {
        fprintf(stderr, "Использование: %s <usual|rt> <sync|async>\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    thread_params_t params;
    params.mode = 0;  

    if (strcmp(argv[1], "usual") == 0) {
        params.signal = SIGUSR1;
        params.expected = 1;
    } else if (strcmp(argv[1], "rt") == 0) {
        params.signal = SIGRTMIN;
        params.expected = 5;  
    } else {
        fprintf(stderr, "Ошибка: первый аргумент должен быть 'usual' или 'rt'.\n");
        exit(EXIT_FAILURE);
    }

    if (strcmp(argv[2], "sync") == 0) {
        params.mode = 0;
    } else if (strcmp(argv[2], "async") == 0) {
        params.mode = 1;
    } else {
        fprintf(stderr, "Ошибка: второй аргумент должен быть 'sync' или 'async'.\n");
        exit(EXIT_FAILURE);
    }

    pthread_t child_tid;

    if (pthread_create(&child_tid, NULL, receiver_thread, &params) != 0) {
        perror("pthread_create");
        exit(EXIT_FAILURE);
    }

    pthread_mutex_lock(&mutex);
    while (!ready) {
        pthread_cond_wait(&cond, &mutex);
    }
    pthread_mutex_unlock(&mutex);

    union sigval sv;
    for (int i = 1; i <= 5; i++) {
        sv.sival_int = i;
        if (pthread_sigqueue(child_tid, params.signal, sv) != 0) {
            perror("pthread_sigqueue");
        } else {
            printf("$ i%d.....\n", i);
        }
        usleep(10000); 
    }


    pthread_mutex_lock(&mutex);
    done = 1;
    pthread_cond_signal(&cond);
    pthread_mutex_unlock(&mutex);

    pthread_join(child_tid, NULL);
    return 0;
}


/*
@debian:~/Desktop$ gcc lab2.c && ./a.out usual sync
$ i1.....
$ i2.....
$ i3.....
$ i4.....
$ i5.....
# START...приемника *****
Сигнал №10 получен, value 1
@debian:~/Desktop$ gcc lab2.c && ./a.out usual async
$ i1.....
$ i2.....
$ i3.....
$ i4.....
$ i5.....
# START...приемника *****
Сигнал №10 получен, value 1
@debian:~/Desktop$ gcc lab2.c && ./a.out rt sync
$ i1.....
$ i2.....
$ i3.....
$ i4.....
$ i5.....
# START...приемника *****
Сигнал №34 получен, value 1
Сигнал №34 получен, value 2
Сигнал №34 получен, value 3
Сигнал №34 получен, value 4
Сигнал №34 получен, value 5
@debian:~/Desktop$ gcc lab2.c && ./a.out rt async
$ i1.....
$ i2.....
$ i3.....
$ i4.....
$ i5.....
# START...приемника *****
Сигнал №34 получен, value 1
Сигнал №34 получен, value 2
Сигнал №34 получен, value 3
Сигнал №34 получен, value 4
Сигнал №34 получен, value 5
@debian:~/Desktop$
 */
Соседние файлы в предмете Системы реального времени