Добавил:
Вуз:
Предмет:
Файл:
practic2
.c#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, ¶ms) != 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$
*/
Соседние файлы в предмете Системы реального времени
