Untitled
unknown
c_cpp
2 years ago
5.3 kB
13
Indexable
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <stdlib.h>
#include <unistd.h>
#include "common.h"
#ifndef countof
#define countof(x) (sizeof( x ) / sizeof( x[0] ))
#endif
#define SELF_NAME "hlgenerator"
static size_t arrsz(const char **arr);
const char *schemes[] = {
"http://",
"https://",
"ftp://",
"news://",
"foobar://",
"data:",
"foo:",
"",
};
const char *users[] = {
"john:doe@",
"smith@",
"123456@",
""
};
const char *domains[] = {
"gosuslugi.ru",
"ietf.org",
"москва.рф",
""
};
const char *ports[] = {
":8080",
":[80]",
"[:80]",
":",
""
};
const char *paths[] = {
"/",
"/foo",
"/foo/",
"/foo/bar",
"/foo/bar/",
""
};
const char *queries[] = {
"?foo=bar&bar=buz",
"?foo=bar&",
"?foo=bar",
"?foo=",
"?foo",
"?",
""
};
const char *anchors[] = {
"#foo%20bar",
"#foo%20",
"#%20foo",
"#foo",
"#",
""
};
const char **sources[] = {
schemes,
users,
domains,
ports,
paths,
queries,
anchors
};
size_t
arrsz(const char **arr) {
size_t n = 0;
do {
n++;
} while (arr[n][0] != '\0');
return ++n;
}
void
generate(int from, int to, int* status) {
size_t idx[countof(sources)], i, j, t;
char buf[1024];
for (i = from; t < to; i++) {
t = i;
buf[0] = '\0';
for (j = 0; j < countof(sources); j++) {
idx[j] = t % arrsz(sources[j]);
if (strlcat(buf, sources[j][idx[j]], sizeof(buf)) >= sizeof(buf)) {
fprintf(stderr, "internal buffer was too small\n");
*status = 1;
return;
}
t /= arrsz(sources[j]);
}
puts(buf);
}
*status = 0;
}
int
main(int argc, char** argv) {
size_t idx[countof(sources)];
int forksCount, status;
pid_t* forks, pid;
// Получить доступное количество ядер
forksCount = sysconf(_SC_NPROCESSORS_ONLN);
fprintf(stderr, "Доступно ядер: %d\n", forksCount);
// Выделение памяти под массив индексов процессов
forks = malloc(forksCount * sizeof(pid_t));
if (forks == NULL) {
fprintf(stderr, "Memory wrong");
return 1;
}
int nvariants = 1; // Количество возможных url
for (size_t i = 0; i < countof(sources); i++) {
nvariants *= arrsz(sources[i]);
}
int from = 0;
int to = nvariants;
// Если один процесс
if (forksCount == 1) {
generate(from, to, &status);
free(forks);
return status;
}
// Получаем разбиение
int dividedBy = (nvariants + forksCount - 1) / forksCount;
fprintf(stderr, "Разделенно на %d частей\n", dividedBy);
// Цикл по всем процессам
for (size_t i = 0; i < forksCount; i++) {
// Создаем дочерний процесс
pid = fork();
if(pid < 0) {
free(forks);
return 1;
}
// Если 0, то мы в дочерном процессе
if(pid == 0) {
from = i * dividedBy;
to = from + dividedBy;
if (to > nvariants) {
to = nvariants;
}
fprintf(stderr, "Запускаю процесс №%d: от %d до %d\n", getpid(), from, to);
generate(from, to, &status);
return status;
}
// Присваиваем индекс процессу
forks[i] = pid;
}
for (size_t i = 0; i < forksCount; i++) {
int fork_status;
// Ждем пока процесс закончится
waitpid(forks[i], &fork_status, 0);
fprintf(stderr, "Процесс %d закончил работу. СТАТУС: %d\n", forks[i],
WEXITSTATUS(fork_status));
status |= WEXITSTATUS(fork_status);
}
fprintf(stderr, "Создано процессов: %d\n", forksCount);
fprintf(stderr, "Все работы %d\n", nvariants);
fprintf(stderr, "Все работы на один процесс %d\n", dividedBy);
free(forks);
return status;
}Editor is loading...
Leave a Comment