Страницы

Поиск по вопросам

Показаны сообщения с ярлыком freebsd. Показать все сообщения
Показаны сообщения с ярлыком freebsd. Показать все сообщения

суббота, 11 апреля 2020 г.

Не работают некоторые сочетания клавиш в консоли FreeBSD

#консоль #shell #freebsd

                    
Я зашёл по ssh на сервер, на котором установлена ОС FreeBSD (например, на хостинге
nic.ru установлена FreeBSD 8.1), и при работе в консоли обнаружил, что некоторые привычные
сочетания клавиш (например, ctrl+стрелка вправо/влево для "перепрыгивания" между словами)
не работают. Вместо ожидаемого действия я получаю в консоль мусорный вывод такого вида:

;5D;5D;5C;5C~~


Как заставить работать сочетания клавиш, которые не работают в консоли FreeBSD "из
коробки"?
    


Ответы

Ответ 1



Дело в ненастроенном readline(3). "Мусор", который видно в терминале - это коды нажатия клавиш и их сочетаний, которым не присвоены никакие функции (чтобы увидеть коды для сочетаний клавиш, которым функции присвоены, можно нажать Ctrl+V и потом интересующее сочетание клавиш (или единичную клавишу) - для кнопки Enter, например, код будет ^M - то есть вместо Enter в консоли можно нажимать Ctrl+M с тем же эффектом, сюрприз!). Уже назначенные на разные клавиши и их сочетания функции можно посмотреть командой bind -lpvs. Для sh и bash настройки readline можно задать в файле .inputrc в домашней папке пользователя. Для реализации неработающих из коробки в FreeBSD сочетаний клавиш я использую следующие настройки: # ~/.inputrc: readline initialization file. # (you can view all current assignments by runnig `bind -lpvs`) # let Insert, PageUP, PageDown keys work properly in bash under FreeBSD and Linux: "\e[2~": overwrite-mode "\e[5~": beginning-of-history "\e[6~": end-of-history # let Ctrl-left-arrow and Ctrl-right-arrow jump over words: "\e[1;5C": forward-word "\eOC": forward-word "\e[1;5D": backward-word "\eOD": backward-word Стоит отметить, что код сочетания клавиш, который можно прочесть с помощью Ctrl+V, может отличаться для разных видов терминалов - например, не совпадать в "обычном" терминале и внутри screen. Вы можете самостоятельно расширить предлагаемый ~/.inputrc для таких случаев.

Может ли Apache работать одновременно с php5_module и module_wsgi?

#python #apache #django #freebsd

                    
Добрый день! Можно ли настроить апач таким образом, чтобы он обрабатывал как страницы,
генерируемые php, так и django? Имеются сайты, сделанные на Drupal 7, теперь вот есть
необходимость разработать сайт на Django. Я буду очень признателен за толковые ответы,
которые направят мой мыслительный процесс в правильное русло.

Обновление

Можете ли поделиться тем, как это реализовать? Или хотя бы ссылку на материалы, где
можно узнать, как все это дело настраивается? Настраивал как описано здесь, но ни к
чему хорошему это не привело. Перестали работать друпаловские сайты.
    


Ответы

Ответ 1



Подобные вопросы были заданы на англояычных сайтах: раз, два. Там в ответах есть примеры конфигов. Если коротко, то нужно выделить для wsgi определенный путь/алиас, а не отдавать ему на обработку все запросы в иерархии сайта.

Ответ 2



да, конечно, можно загрузить и использовать оба модуля, если под вторым имелся в виду модуль wsgi. обновление по приведённой ссылке, насколько я вижу, не сказано о том, что предлагаемые строки конфигурации надо вносить в отдельный virtualhost. вероятно, имеет смысл дополнить ваш вопрос информацией вида: есть virtualhost такого-то содержания, добавляю virtualhost такого-то содержания и от первого virtualhost-а в логе появились такие-то ошибки.

понедельник, 30 марта 2020 г.

Таблицы ipfw FreeBSD. Для чего нужны?

#freebsd #ipfw


Подскажите в чем сила таблиц в ipfw? Ведь можно нужные ip-адреса записывать в переменные??
Например, в файле с настройками ipfw задаем переменную Lan="192.168.0.0/24,192.168.1.2".
Понятно, что если нужно добавить другой адрес, то придется перегрузить ipfw. Однако
если использовать таблицы, то их так же нужно прописывать в файле с настройками ipfw.

table_icmp=1
${cmd} table $table_icmp flush
${cmd} table $table_icmp add 192.168.0.0/24
${cmd} table $table_icmp add 192.168.1.2


И при добавлении нового ip-адреса перегружать ipfw. Единственным плюсом является
добавление адресов в таблицу (до первой перегрузки ipfw или системы)

ipfw table 1 add 192.168.1.4


Где их стоит применять?? 
    


Ответы

Ответ 1



Таблицы в ipfw это динамический массив. Применяются как раз для того чтобы не надо было перегружать правила всего файрвола. Изначально таблица вообще может быть пустой и изменяться в процессе работы какого-то демона. Как пример, можно посмотреть демон /usr/ports/security/py-fail2ban Он анализирует логи и если кол-во, например, неправильных попыток ввода пароля по ssh превысило 3, то этот IP адрес в носится в таблицу 22. А в правилах прописывается: unreach port ip from table(22) to me

Ответ 2



Таблицы быстры. Думаю, что в отличие от пробегания по правилам, поиск по таблицам осуществляется не последовательным перебором, а с использованием какого-либо дерева. Кроме того, они позволяют сокращать набор правил, если одно и то же правило будет применяться ко множеству адресов. В общем, место для использования таблиц — это когда вам надо применить одно правило для большого количества (от десятка до десятков тысяч) адресов, особенно, когда набор этих адресов динамически меняется, а не сохранён в файле конфигурации.

четверг, 13 февраля 2020 г.

Освобождение ресурсов, выделенных потоку

#c #память #unix #freebsd #pthread


Всем добрый день!
Хотелось бы обсудить следующую проблему : в программе средствами библиотеки pthread
создается поток, ОС выделяет ему некоторый обьем памяти на стек и т.п., после того,
как данный поток отработал и завершился, из другого потока вызывается pthread_join(),
забирающая код возврата. При этом, не заметно, чтобы память, выделенная для данного
потока, освобождалась (при вызове pthread_create() выделилось порядка 100 кб, из которых
ничего не освободилось ни после return(), ни после pthread_join()). Кто-нибудь может
пояснить, почему? Я что-то не так делаю, или это может быть обусловлено поведением ОС ?    


Ответы

Ответ 1



@margosh, я тоже (солидарно с @mikillskegg и почти интуитивно) считаю, что память, которую брал поток, используется повторно. Иллюстрацию приведу прямо здесь. #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define fatal(msg) ({perror(msg); exit(-1);}) pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; int nth = 0; void * thcli (void *a) { pthread_mutex_lock(&lock); nth--; pthread_mutex_unlock(&lock); return (void *)1; } int main (int ac, char *av[]) { int i, n = av[1]? atoi(av[1]):100; if (n < 1) n = 100; pthread_t th[n]; void *res[n]; char buf[100]; do { pthread_mutex_lock(&lock); for (i = 0; i < n; i++) { if (pthread_create (&th[i], NULL, thcli, NULL)) fatal("create"); nth++; } printf ("run %d nth = %d\n",i,nth); pthread_mutex_unlock(&lock); for (i = 0; i < n; i++) { if (pthread_join (th[i], &res[i])) fatal("join"); } printf ("join %d nth = %d\nAgain ?\n",i,nth); } while (fgets(buf,sizeof(buf),stdin), buf[0] == 'y'); exit (puts("Bye") == EOF); } Обилия инклюдов не пугайтесь, большая часть на нужны, просто скопировал для этого тестика из другой программы. А вот и иллюстация avp@avp-xub11:~/src/ig/tst$ gcc th.c -pthread ..... avp@avp-xub11:~/src/ig/tst$ ./a.out 381 create: Cannot allocate memory avp@avp-xub11:~/src/ig/tst$ ./a.out 380 run 380 nth = 380 join 380 nth = 0 Again ? y run 380 nth = 380 join 380 nth = 0 Again ? y run 380 nth = 380 join 380 nth = 0 Again ? y run 380 nth = 380 join 380 nth = 0 Again ? . Bye avp@avp-xub11:~/src/ig/tst$ ./a.out 380 run 380 nth = 380 join 380 nth = 0 Again ? y run 380 nth = 380 join 380 nth = 0 Again ? . Bye avp@avp-xub11:~/src/ig/tst$ ./a.out 381 create: Cannot allocate memory avp@avp-xub11:~/src/ig/tst$ IMHO видно, что если ресурса почти достаточно, то после завершения потоков он опять высвобождается и повторно используется (по крайней мере в такой же ситуации). UPD-1 @margosh, у меня в линуксе не растет. Добавил функцию // returns second field for last line selected by 'what' static int pri_mem (int pid, char **what) { char path[1000]; int res = 0; sprintf (path,"/proc/%d/status",pid); FILE *in = fopen(path,"r"); if (!in) { perror(path); return; } while (fgets(path,1000,in)) { char **w = what; while (*w) { if (strncasecmp(path,*w,strlen(*w)) == 0) { fputs(path,stdout); char dummy[1000]; sscanf(path,"%s %d",dummy,&res); break; } w++; } } fclose(in); return res; } и чуть изменил main(), теперь печатает память перед каждым циклом avp@avp-xub11:~/src/ig/tst$ gcc th.c -pthread avp@avp-xub11:~/src/ig/tst$ ./a.out 380 VmPeak: 2252 kB VmSize: 2252 kB VmHWM: 312 kB VmRSS: 312 kB VmStk: 136 kB run 380 nth = 380 loop 0: join 380 nth = 0 Exit ? VmPeak: 3116732 kB VmSize: 35044 kB VmHWM: 2180 kB VmRSS: 680 kB VmStk: 136 kB run 380 nth = 380 loop 1: join 380 nth = 0 Exit ? VmPeak: 3116736 kB VmSize: 35044 kB VmHWM: 2192 kB VmRSS: 692 kB VmStk: 136 kB run 380 nth = 380 loop 2: join 380 nth = 0 Exit ? VmPeak: 3116736 kB VmSize: 35044 kB VmHWM: 2192 kB VmRSS: 692 kB VmStk: 136 kB run 380 nth = 380 loop 3: join 380 nth = 0 Exit ? и дальше VmPeak: 3116736 kB VmSize: 35044 kB VmHWM: 2192 kB VmRSS: 692 kB VmStk: 136 kB run 380 nth = 380 loop 29: join 380 nth = 0 Exit ? VmPeak: 3116736 kB VmSize: 35044 kB VmHWM: 2192 kB VmRSS: 692 kB VmStk: 136 kB run 380 nth = 380 loop 30: join 380 nth = 0 Exit ? VmPeak: 3116736 kB VmSize: 35044 kB VmHWM: 2192 kB VmRSS: 692 kB VmStk: 136 kB run 380 nth = 380 loop 31: join 380 nth = 0 Exit ? y Bye avp@avp-xub11:~/src/ig/tst$ IMHO не растет. Попробуем с небольшим количеством потоков avp@avp-xub11:~/src/ig/tst$ ./a.out 30 VmPeak: 2252 kB VmSize: 2252 kB VmHWM: 316 kB VmRSS: 316 kB VmStk: 136 kB run 30 nth = 30 loop 0: join 30 nth = 0 Exit ? VmPeak: 248132 kB VmSize: 35044 kB VmHWM: 728 kB VmRSS: 628 kB VmStk: 136 kB run 30 nth = 30 loop 1: join 30 nth = 0 Exit ? VmPeak: 248136 kB VmSize: 35044 kB VmHWM: 740 kB VmRSS: 640 kB VmStk: 136 kB run 30 nth = 30 loop 2: join 30 nth = 0 Exit ? ....... ....... loop 15: join 30 nth = 0 Exit ? VmPeak: 248136 kB VmSize: 35044 kB VmHWM: 740 kB VmRSS: 640 kB VmStk: 136 kB run 30 nth = 30 loop 16: join 30 nth = 0 Exit ? VmPeak: 248136 kB VmSize: 35044 kB VmHWM: 740 kB VmRSS: 640 kB VmStk: 136 kB run 30 nth = 30 loop 17: join 30 nth = 0 Exit ? y Bye avp@avp-xub11:~/src/ig/tst$ Возможно проблема в FreeBsd.

Ответ 2



Странно, что никто не сказал про pthread_detach(). Помнится если его не запускать память выделенная под поток не освобождается и очень шустро растет, что очень заметно например в htop. Я вызываю эту штуку после pthread_create(). pthread_t restrict; if(pthread_create(&restrict, ...)) return 0; pthread_detach(restrict); return 0; "Функция pthread_join блокирует работу вызвавшей ее нити исполнения до завершения thread'а с идентификатором thread." Не вижу никакой связи с использованием памяти. Она тут не при чем.

Ответ 3



лимит комментов исчерпан. @avp, -D_THREAD_SAFE не спас. Возможно, прийдется пересмотреть логику очищения, в любом случае попробую и с detach для разнообразия, вдруг изменится чего. да, join сейчас только 1 поток делает, когда получает признак через pipe(), как Вы мне когда-то подсказали уже, за что большое спасибо :)

Доставка сигналов только одному потоку : может ли часть потеряться?

#c #unix #freebsd #pthread


Всем добрый день!
Если доставка некоторого сигнала разрешена только одному из потоков, может ли на
практике быть случай, когда несколько однотипных сигналов (SIGCHLD) будут посланы практически
одновременно, и процессор не успеет переключиться на данный поток вовремя, вследствии
чего обработчик сигнала выполнится 1 раз вместо, к примеру, 3-х ?     


Ответы

Ответ 1



Да, есть проблема. Если несколько сигналов SIGCHLD одновременно ждут доставки, будет доставлен лишь один сигнал. Источник. Там же рекомендация по обходу проблемы. Вот ещё, судя по всему, полезная информация по теме: handling SIGCHLD with multiple children.

Ответ 2



Может. В системе нет очереди сигналов, есть только битовая маска, приходящий сигнал выставляет там бит, при вызове обработчика (или действию по умолчанию) система сбрасывает этот бит.

Ответ 3



Не путаем понятия потоки (threads) и процессы (process). Процесс может содержать в себе несколько потоков (тредов или нитей). Если используешь сигналы, то он направляется конкретно процессу, а значит обработчику сигнала в этом процессе. man sigaction man signal

воскресенье, 9 февраля 2020 г.

Linux/*NIX и аргументы программы

#linux #bash #консоль #freebsd


Интересует вопрос, каким образом работают аргументы программы на разных ОС (Debian/Linux,
FreeBSD, Solaris, etc).

Для примера, возьмём стандартную программу  ls, и запустим её с аргументами -a -l.
Получим вывод. Однако, запустив ls -la, ls -al, ls -l -a - мы получим тот же вывод.
Хотелось бы узнать - данное поведение как-то контролируется разработчиками? Например,
я напишу программу, которая будет работать со следующими аргументами: -R -t -dT, как
юзер сможет запустить программу, как показано на примере ls? Это 'регулируется' автором
тулзы?
    


Ответы

Ответ 1



Это 'регулируется' автором тулзы? И да и нет. Программист сознательно должен предусмотреть это в своей программе, но для этого есть стандартная библиотечная функция — getopt() и встроенная команда оболочки getopts. Обе они стандартизированы POSIX. Интерфейсы к getopt есть практически во всех языках. Например, я напишу программу, которая будет работать со следующими аргументами: -R -t -dT, Подразумевая, что это -d и -T — это два разных ключа, на Си типовой пример обработки будет выглядеть примерно так: #include #include #include void usage(const char* name) { printf(stderr, "Usage: %s" -[RtdT] [-f ], name); } int main (int argc, char **argv){ bool recursive=0; bool show_directory=0 bool super_time=0; char *file; int c; while ((c = getopt (argc, argv, "RtdTf:")) != -1) { switch (c) { case 'R': recursive = 1; break; case 't': process_time = 1; break; case 'd': show_directorye = 1; break; case 'T': process_time = 0; break; case 'f': file = optarg break; case 'h': usage(argv[0]); return EXIT_SUCCESS; case '?': return EXIT_FAILURE; default: assert(0); } } // do stuff return EXIT_SUCCESS; } glibc также предоставляет функцию getopt_long (), которая поддерживает парсинг длинных аргументов вида --some-option и --some-option-with-arg=val, но это только расширение GNU. Для примера, возьмём стандартную программу ls, и запустим её с аргументами -a -l. Получим вывод. Такое поведение большинства утилит, кстати также стандартизовано POSIX.

воскресенье, 26 января 2020 г.

Менять пароль пользователя в ходе выполнения скрипта

#c #users #freebsd


Доброго времени суток, у меня стоит интересная задачка в ходе корой мне необходимо
менять пароль пользователя в ходе выполнения скрипта. Из всего что я знаю о фряхе я
остановился на команде passwd, но так как она получает пароль только при вводе, пытался
вызвать ее через popen и в поток забить новый пасс, но увы ничего не удалось...
P.S. по факту мне нужно создать пользователя, но команда pw не принимает пароль,
насколько я понял. и связи с этим приходится искать решение выше указанного геморроя    


Ответы

Ответ 1



Думаю, man 3 forkpty это то, что Вам нужно. Там через псевдотерминал (pty) надо работать. В принципе, не очень сложно написать некий двунаправленный аналог popen() на псевдотерминале вместо pipe. Например, expect делает так в spawn. Например, можно почитать здесь. Или покороче здесь. Идея в том, что Вы делаете псевдотерминал (это как бы связка из двух устройств -- master и slave (ведет себя аналогично обычному tty)), делаете fork и там dup дескрипторов 0,1,2 на slave, после exec passwd она считает, что работает с терминалом. Родительский процесс обменивается байтиками по master. ответ составлен из комментариев, написанных avp к вопросу.

Запись в конец файла без вычисления смещения

#freebsd


Можно ли с помощью vn_rdwr(9) дописывать в конец файла, не вычисляя само смещение?
Насколько я понял, есть ещё функции для записи из ядра FreeBSD в файл: vn_write(9),
VOP_WRITE(). В VOP_ACCESS можно выставить флаг VAPPEND. Но как этим пользоваться -
не знаю. Где описаны (исходный код) функции типа VOP_ACCESS_APV() и VOP_WRITE_APV()?
    


Ответы

Ответ 1



На python, я бы долго не думал, если костыль надо наскоро забить: import commands import time filename = 'big.log' new_message = str( time.ctime() ) + ': New message' commands.getoutput('/bin/echo "' + new_message + '" >> ' + filename ) Должно сработать, и копал бы я именно вокруг >> для нахождения исходных Сишных команд.

четверг, 23 января 2020 г.

В чем разница между bintime() и nanotime()?

#freebsd #kernel


В чем разница между nanotime(9) и bintime(9), если возвращаемое значение bintime(struct
bintime) можно конвертировать c помощью bintime2timespec в значение nanotime(timespec)?
    


Ответы

Ответ 1



bintime использует структуры с более натуральными полями, арифметика над которыми значительно проще, и потому их использование более эффетивно. Текущие версии ядра и системных утилит используют именно bintime структуры для операций с отметками времени, переводя в други форматы только при необходимости. Грубо говоря, nanotime реализовано через bintime.

суббота, 11 января 2020 г.

Что такое smoke test и с чем его едят?

#linux #shell #freebsd #test_automation


Что такое smoke test? Гугл дал только краткую формулировку, а хотелось бы с конкретными
примерами, литературой и т. д. Как можно запустить данные тесты ( какие команды в shell'е
) в разных unix подобных ос для разных утилит. Насколько я понимаю, для каждой программы
есть определенный набор команд ( tool -h или -version ), и проверив работоспособность
такого manpage можно сказать, что данная утилита прошла smoke test или нет.
    


Ответы

Ответ 1



какие команды в shell'е Проще всего: if tool -h then echo "Прошли smoke test" else echo "Не прошли smoke test" if tool --version then echo "Прошли smoke test" else echo "Не прошли smoke test" Но не факт, что все разработчики tool достаточно добросовестны и снабдили свой tool обработкой этих опций.

Ответ 2



Только проверку того, что тулза скомпилировалась - сложно назвать smoke-test. Smoke-test должен поверхностно протестировать наличие и корректную работу в тривиальных случаях всех самых важных функций тестируемой системы. Основная задача - охватить как можно больше функциональности за кратчайшее время. Никаких сложных кейсов. Цель - выявление проблем со сборкой перед её скармливанием более глубоким методам тестирования, экономия времени, очистка истории сборок от случайных ошибок. Дымовое тестирование имеет смысл размещать не на серверах CI, а у конкретных разработчиков либо на хуки системы контроля версий на development сервере. Его, в принципе, можно не автоматизировать(хотя тогда есть риск его пропустить). Разработчик может просто самостоятельно пробежаться по всем(не только по тем, в которые он вносил изменения) важным узлам билда вручную - это тоже вполне себе smoke-тестирование По поводу утилит, вы используете привычные вам методы тестирования, различие только в наборе тестов - вы идёте не в глубину, а в ширину.

Ответ 3



Само выражение smoke test - пришло из электроники. Собрали вы новое устройство, включили его в розетку, а оно громко бабахнуло и выпустило белый дым - значит smoke test не пройден. В программировании smoke test обозначает достаточно быстрый тест самой важной функциональности. Какой именно, зависит от программы. Например для интернет браузера будет достаточно открыть какой-нибудь https://google.com

среда, 1 января 2020 г.

Короткая инструкция для относителных путей

#linux #freebsd


При использовании относительных путей например cd ./../../../.. хочется использовать
какой нибудь сокращенный эквивалент этой команды, что то похожее на  ..\4 .

Может в POSIX системах есть, что то похожее на это ?
    


Ответы

Ответ 1



Вы можете сами назначить алиасы, например такие: alias ..="cd .." alias ...="cd ../.." alias ....="cd ../../.." alias .....="cd ../../../.." alias ......="cd ../../../../.." Или такие: alias ..="cd .." alias ..2="cd ../.." alias ..3="cd ../../.." alias ..4="cd ../../../.." alias ..5="cd ../../../../.."

Ответ 2



поступил вот так. написал скрипт на баше #!/bin/bash i=1 while [ "$i" -le "$1" ]; do i=$(($i + 1)) str=$str"../" done echo $str и вот так его вызываю: cd `имя_скрипта 7` 7 - это количество директорий на которые нужно вернутся. если кто то может улучшить этот скрипт то буду этому рад _____________ 17.10.2017 ______________ скрипт был усовершенствован до такого вида #!/bin/bash i=1 while [ "$i" -le "$1" ]; do i=$(($i + 1)) ss=$ss"../" done cd $ss unset ss затем создаем вот такой алиас alias cdn='. имя_скрипта ' и теперь его можно вызывать вот так: cdn 6 цыфра в конце это количество директорий на которые необходимо вернутся

вторник, 31 декабря 2019 г.

Возможно ли управлять распределением потоков по ядрам процессора?

#c #многопоточность #unix #freebsd


Всем добрый день!
 Рассматриваю возможности реализации нового сервера, и пока остановилась на модели
с созданием пула потоков. Однако поступила информация, что при такой работе сервера
на многоядерной системе, определенные потоки будут закреплены за ядрами сразу и перераспределения
их не будет, пока они не будут уничтожены, то есть возможна ситуация, когда часть пула
потоков, которая на данный момент никаких активных действий не производит, будет висеть
на одном ядре, и оно фактически будет простаивать, в то время, как второе ядро будет
загружено несколькими активными потоками. Если кто-то в курсе, подскажите плиз, действительно
ли это так, и есть ли какой-то способ управлять распределением потоков по ядрам, чтобы
загружать их более-менее равномерно? Может кто-то может полезной ссылочкой поделиться
применительно к unix - я ничего толкового пока не нашла по этому вопросу.    


Ответы

Ответ 1



Ручное распределение потоков по ядрам нужно только в очень исключительных случаях. Система будет перераспределять потоки между ядрами, как ей кажется правильно. И может перебросить рабочий тред с одно ядра на другое но в 99% это не нужно. Давайте представим некую виртуальную систему с 16 ядрами и 100 потоками. и 10 из них активно работает, занимая при это 10 ядер. Остальные 90 сидят тихонько на оставшихся 6. Вопрос, есть ли смысл перебрасывать активный поток на другое ядро? Ответ - нет. Только хуже сделаем (накладные расходы на переключение). Поэтому система будет пытаться сохранить поток на своем ядре. Вариант, когда ядер 2 и 100 потоков (из них 10 активных). В этом случае загружены будут точно два ядра. Причем выиграш от того, что есть 10 активных потоков будет отрицательный. Именно по этой причине, когда создают пул потоков, которые нагружены одинаково, не делают их больше кол-ва ядер+1. Потому что при дальнейшем увеличении кол-ва потоков будет только падение производительности (накладные расходы на переключение. Процессор только тем будет и заниматься, что переключать контексты потоков). В случае одного ядра, не рекомендуется создавать более 16 потоков на процесс (это конечно устаревшая информация, данная Борландом в году так 1995-1997 и в век двухядерных процессоров у каждой домохозяйки в ноуте и в планшете она малоактуальна). Но есть вариант, когда много потоков может улучшить задачу - это когда потоки занимаются малоактивной работой. Но преимущество только одно - упрощается логика кода. Но это сильно зависит от задачи. А теперь подсуммируем. Если у вас сервер с 2 ядрами, то на данный момент это не сервер, а домашний компьютер. Будете делать пул потоков - сделайте возможность регулировать кол-во потоков в пуле и проведите замеры. Очень часто, выставив правильное кол-во потоков, можно сильно ускорить задачу. А в некоторых случаях может выяснится, что оптимально будет работать только при одном потоке. Не доверяйте русскоязычному переводу англоязычной документации. В спорных случаях обращайтесь к английскому оригиналу. У меня был случай, когда из за неточностей в одно слово в переводе мана по select смысл очень сильно менялся

пятница, 13 декабря 2019 г.

FreeBSD gcc install

#gcc #freebsd


Здравствуйте.
Стараюсь поставить на FreeBSD 7 x64 gcc посвежее родного 4.2.1.
Из портов не ставится. Жалуется на отсутсвие GMP и MPFR (или их кривой путь).
По этому ответу поставил нужные библиотеки и с их помощью конфигурил make, который
потомвыдавал:

Error expanding embedded variable.
Error code 2


Пробовал так же по вышеуказанному ответу собирать gmake'ом, но процесс съедает всю
оперативку, и завершается:

virtual memory exhausted: Cannot allocate memory
gmake[2]: *** [insn-recog.o] Error 1
gmake[2]: Leaving directory `/root/tmp/gcc-4.9.1/host-x86_64-unknown-freebsd7.2/gcc'
gmake[1]: *** [all-gcc] Error 2
gmake[1]: Leaving directory `/root/tmp/gcc-4.9.1'
gmake: *** [all] Error 2


Прошу помочь разобраться с этим вопросом.
    


Ответы

Ответ 1



Как насчет дополнительного свапа? Создайте файл нужного размера при помощи dd dd if=/dev/zero of=/usr/swap0 bs=1m count=64 Затем его нужно разметить как swap mkswap /usr/swap0 И задействовать swapon /usr/swap0

понедельник, 15 июля 2019 г.

Зачем нужны параметры newp, newLen в функции sysctl()?

В документации по функции sysctl написано следующее:
To set a new value, newp is set to point to a buffer of length newlen from which the requested value is to be taken. If a new value is not to be set, newp should be set to NULL and newlen set to 0.
Но я не могу понять, что это означает.


Ответ

Дословный перевод:
Чтобы установить новое значение, newp указывает на буфер длиной newlen, из которого берется запрашиваемое значение. Если новое значение не устанавливается, то newp должен быть задан в NULL, а newlen в 0.

среда, 20 марта 2019 г.

Менять пароль пользователя в ходе выполнения скрипта

Доброго времени суток, у меня стоит интересная задачка в ходе корой мне необходимо менять пароль пользователя в ходе выполнения скрипта. Из всего что я знаю о фряхе я остановился на команде passwd, но так как она получает пароль только при вводе, пытался вызвать ее через popen и в поток забить новый пасс, но увы ничего не удалось... P.S. по факту мне нужно создать пользователя, но команда pw не принимает пароль, насколько я понял. и связи с этим приходится искать решение выше указанного геморроя


Ответ

Думаю, man 3 forkpty это то, что Вам нужно.
Там через псевдотерминал (pty) надо работать. В принципе, не очень сложно написать некий двунаправленный аналог popen() на псевдотерминале вместо pipe. Например, expect делает так в spawn
Например, можно почитать здесь. Или покороче здесь. Идея в том, что Вы делаете псевдотерминал (это как бы связка из двух устройств -- master и slave (ведет себя аналогично обычному tty)), делаете fork и там dup дескрипторов 0,1,2 на slave, после exec passwd она считает, что работает с терминалом. Родительский процесс обменивается байтиками по master

ответ составлен из комментариев, написанных avp к вопросу.

суббота, 16 марта 2019 г.

В чем разница между bintime() и nanotime()?

В чем разница между nanotime(9) и bintime(9), если возвращаемое значение bintime(struct bintime) можно конвертировать c помощью bintime2timespec в значение nanotime(timespec)?


Ответ

bintime использует структуры с более натуральными полями, арифметика над которыми значительно проще, и потому их использование более эффетивно. Текущие версии ядра и системных утилит используют именно bintime структуры для операций с отметками времени, переводя в други форматы только при необходимости. Грубо говоря, nanotime реализовано через bintime

вторник, 8 января 2019 г.

Возможно ли управлять распределением потоков по ядрам процессора?

Всем добрый день! Рассматриваю возможности реализации нового сервера, и пока остановилась на модели с созданием пула потоков. Однако поступила информация, что при такой работе сервера на многоядерной системе, определенные потоки будут закреплены за ядрами сразу и перераспределения их не будет, пока они не будут уничтожены, то есть возможна ситуация, когда часть пула потоков, которая на данный момент никаких активных действий не производит, будет висеть на одном ядре, и оно фактически будет простаивать, в то время, как второе ядро будет загружено несколькими активными потоками. Если кто-то в курсе, подскажите плиз, действительно ли это так, и есть ли какой-то способ управлять распределением потоков по ядрам, чтобы загружать их более-менее равномерно? Может кто-то может полезной ссылочкой поделиться применительно к unix - я ничего толкового пока не нашла по этому вопросу.


Ответ

Ручное распределение потоков по ядрам нужно только в очень исключительных случаях. Система будет перераспределять потоки между ядрами, как ей кажется правильно. И может перебросить рабочий тред с одно ядра на другое но в 99% это не нужно. Давайте представим некую виртуальную систему с 16 ядрами и 100 потоками. и 10 из них активно работает, занимая при это 10 ядер. Остальные 90 сидят тихонько на оставшихся 6. Вопрос, есть ли смысл перебрасывать активный поток на другое ядро? Ответ - нет. Только хуже сделаем (накладные расходы на переключение). Поэтому система будет пытаться сохранить поток на своем ядре. Вариант, когда ядер 2 и 100 потоков (из них 10 активных). В этом случае загружены будут точно два ядра. Причем выиграш от того, что есть 10 активных потоков будет отрицательный. Именно по этой причине, когда создают пул потоков, которые нагружены одинаково, не делают их больше кол-ва ядер+1. Потому что при дальнейшем увеличении кол-ва потоков будет только падение производительности (накладные расходы на переключение. Процессор только тем будет и заниматься, что переключать контексты потоков). В случае одного ядра, не рекомендуется создавать более 16 потоков на процесс (это конечно устаревшая информация, данная Борландом в году так 1995-1997 и в век двухядерных процессоров у каждой домохозяйки в ноуте и в планшете она малоактуальна). Но есть вариант, когда много потоков может улучшить задачу - это когда потоки занимаются малоактивной работой. Но преимущество только одно - упрощается логика кода. Но это сильно зависит от задачи. А теперь подсуммируем. Если у вас сервер с 2 ядрами, то на данный момент это не сервер, а домашний компьютер. Будете делать пул потоков - сделайте возможность регулировать кол-во потоков в пуле и проведите замеры. Очень часто, выставив правильное кол-во потоков, можно сильно ускорить задачу. А в некоторых случаях может выяснится, что оптимально будет работать только при одном потоке. Не доверяйте русскоязычному переводу англоязычной документации. В спорных случаях обращайтесь к английскому оригиналу. У меня был случай, когда из за неточностей в одно слово в переводе мана по select смысл очень сильно менялся

воскресенье, 21 октября 2018 г.

FreeBSD gcc install

Здравствуйте. Стараюсь поставить на FreeBSD 7 x64 gcc посвежее родного 4.2.1. Из портов не ставится. Жалуется на отсутсвие GMP и MPFR (или их кривой путь). По этому ответу поставил нужные библиотеки и с их помощью конфигурил make, который потомвыдавал:
Error expanding embedded variable. Error code 2
Пробовал так же по вышеуказанному ответу собирать gmake'ом, но процесс съедает всю оперативку, и завершается:
virtual memory exhausted: Cannot allocate memory gmake[2]: *** [insn-recog.o] Error 1 gmake[2]: Leaving directory `/root/tmp/gcc-4.9.1/host-x86_64-unknown-freebsd7.2/gcc' gmake[1]: *** [all-gcc] Error 2 gmake[1]: Leaving directory `/root/tmp/gcc-4.9.1' gmake: *** [all] Error 2
Прошу помочь разобраться с этим вопросом.


Ответ

Как насчет дополнительного свапа? Создайте файл нужного размера при помощи dd
dd if=/dev/zero of=/usr/swap0 bs=1m count=64
Затем его нужно разметить как swap
mkswap /usr/swap0
И задействовать
swapon /usr/swap0