Monday, June 11, 2007

Азы программирования под *nix

Немного разобрался с программированием под Unix. Нужно заметить, что для людей которые программировали под Windows - будет проблематично перейти под *nix, но это исключительно мое субъективное мнение.
Итак, начнем. Что нужно усвоить обязательно - это вызов функции fork().
В двух словах. fork() - функция порождает дочерний процесс на основе родительского, не наследует только семафоры. При корректной отработки функции у нас получается дочерний процесс с идентификатором 0 и родительский с PID дочернего. После вызова данной функции вызывается вначале
дочерний процесс, а уже потом родительский.
Более подробную информанию можно почитать в мануалах.
А теперь перейдем непосредственно к программированию (см. в комментарии)

4 comments:

Unknown said...

Задача №1: подсчет слов в трех файлах.

#include "stdio.h"
#include "stdlib.h"
#include "unistd.h"

void thread_work(char *filename)
{
pid_t pid;
char *arglist[4];

arglist[0]="wc";
arglist[1]="-w";
arglist[2]=filename;
arglist[3]=0;

pid = fork();
if (pid == 0) {
execvp("wc", arglist);
exit(0);
}
}

int main(int argc, char *argv[])
{
pid_t pid;

if (argc < 4) {
printf("wc3 filename1 filename2 filename3\n");
return 1;
}

thread_work(argv[1]);
thread_work(argv[2]);
thread_work(argv[3]);

return 0;

}

Unknown said...

Задача №2: написать программу аналог комманды who|wc. Впринципе ниже приведенная программа приспособлена для любых комманд с одним пайпом.

#include "stdio.h"
#define READ 0
#define WRITE 1
main(int argc, char *argv[])
{
int fd[2];
pipe(fd); //создается пайп
pid_t pid = fork();
if (fork()!=0) //родитель будет писать
{close(fd[READ]); //закрываем ненужный конец чтения
dup2(fd[WRITE],1); //записали вывод, который будет дублироваться
execlp(argv[1],argv[1],NULL); //запуск писания
}
else //ребенок читает
{close(fd[WRITE]); //закрываем неиспользуемый конец для записи
dup2(fd[READ],0); //дублируем используемый конец в stdiо
execlp(argv[2],argv[2], "-l", NULL); //запуск читателя
}
}

Unknown said...

Задача №3: написать программу аналог комманды ls|who -l > file.txt (я думаю, что нетрудно заменить некоторые комманды на требуемые)

int main() {
int pipe_fd[2];
pipe(pipe_fd);
pid_t pid = fork();
if (pid == 0) {
close(*(pipe_fd + 1));
int fd = open("file.txt", O_CREAT | O_WRONLY | O_TRUNC, 0644);
dup2(fd, STDOUT_FILENO);
dup2(*pipe_fd, STDIN_FILENO);
execlp("wc", "wc", NULL);
} else if (pid < 0) {
perror(NULL);
_exit(errno);
}
close(*pipe_fd);
dup2(*(pipe_fd + 1), STDOUT_FILENO);
execlp("ls", "ls", "-l", NULL);
return 0;

}

Unknown said...

Задача №4: просто пример работы с потоками, выводит на экран "Hello world"

#include "pthread.h"
#include "stdio.h"
void* thread_proc_hello(void* data)
{
printf("hello ");
return NULL;
}

void* thread_proc_world(void* data)
{
printf("world");
return NULL;
}

int main(int argc, char *argv[])
{
pthread_t thread1, thread2;
pthread_create(&thread1, NULL, &thread_proc_hello, NULL);
pthread_create(&thread2, NULL, &thread_proc_world, NULL);
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
return 0;

}