• Revista PROGRAMAR: Já está disponível a edição #53 da revista programar. Faz já o download aqui!

Rorsch

[Resolvido] Processos que criam a sua própria estructura em vez de uma comum

17 mensagens neste tópico

Tenho a seguinte estructura de dados num .h partilhado por todos:

struct registo {
        int money;
        int ident;
};

struct apostas {
        int fichas;
        int aposta;
        int ident;
};

Inicializo estas estructuras antes do main do ficheiro que cria os processos.

struct registo credito[7];
struct apostas mesa[7];

Depois, para cada processo lanço uma função que está noutro ficheiro .c. No ínicio desse ficheiro fiz:

extern struct registo credito[];
extern struct apostas mesa[];

O meu problema é que para cada processo filho tenho uma estructura de dados nova, em vez de uma comum entre todos  :wallbash:

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Não percebi muito bem o teu post, mas parece que o teu problema está em usares processos, quando devias usar threads. Os processos não partilham variáveis.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Não percebi muito bem o teu post, mas parece que o teu problema está em usares processos, quando devias usar threads. Os processos não partilham variáveis.

if ((childpid = fork()) < 0)
     err_dump("server: fork error");
else if (childpid == 0) {
     close(sockfd);
     str_echo(newsockfd);

Ele lança um processo filho para a função str_echo. Mas dado que o cabeçalho dessa função é um extern para a estructura de dados definida no main, não devia ser comum a todos os processos filhos?

main.c -> inicialização da estructura; chama str_echo (util.c) para cada processo filho;

util.c -> cabeço com os externs para a estructura; e faz a execução dos processos filhos;

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Ele lança um processo filho para a função str_echo. Mas dado que o cabeçalho dessa função é um extern para a estructura de dados definida no main, não devia ser comum a todos os processos filhos?

Não me parece. Lançares um novo processo penso que é o mesmo que iniciares um novo programa. Não partilham "nada".

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Não me parece. Lançares um novo processo penso que é o mesmo que iniciares um novo programa. Não partilham "nada".

mas eles vão buscar os dados a uma estructura externa não é?

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Qual a maneira mais fácil para resolver o meu problema? Mandar para cada processo filho apontadores para a estructura?

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Penso que o melhor seria usar threads. Caso contrário, a única forma que estou a ver é usar ficheiros/pipes.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Penso que o melhor seria usar threads. Caso contrário, a única forma que estou a ver é usar ficheiros/pipes.

em vez de fazer o fork faço uma thread? dessa maneira eles partilham a estructura?

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

As threads devem partilhar as variáveis que estão na heap (apenas a stack é local a cada thread). Basta que coloques a estrutura na heap para a partilhares.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Qual a maneira mais fácil para resolver o meu problema? Mandar para cada processo filho apontadores para a estructura?

Não podes fazer isto. O acesso à memória não seria permitido pelo sistema operativo. Podias usar memória partilhada, mas isto levava a precisares de mecanismos de sincronização entre os processos para que não existissem 2 processos a alterar os dados dessa estrutura "ao mesmo tempo". Eu acho que o melhor é seguires o conselho do Rui Carlos.

As threads também partilham as variáveis globais que pelo que me disseram aqui, não estão na heap (estou a assumir que este ponto é igual em C e C++).

Não me parece. Lançares um novo processo penso que é o mesmo que iniciares um novo programa. Não partilham "nada".

Depende como iniciares o processo. Se for com fork(), o processo filho herda todas as variáveis e respectivos valores do processo pai até esse momento (note-se que são copias das variaveis. Não tenho a certeza como funcionam os apontadores neste caso, mas penso que o processo filho só fica com copias das coisas, por isso acho que continua a não ser possível fazer o que pretendes com o fork). Se for com uma função da familia exec*(), o processo é lançado como um novo programa sem partilharem nada.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

As threads também partilham as variáveis globais que pelo que me disseram aqui, não estão na heap (estou a assumir que este ponto é igual em C e C++).

Os lugares onde as variáveis são armazenadas deve depender do compilador, assim como a forma como as threads são implementadas. Mas pelo menos quando usamos GNU Portable Threads, a stack não é partilhada.

process vs. thread

A process on Unix systems consists of at least the following fundamental ingredients: virtual memory table, program code, program counter, heap memory, stack memory, stack pointer, file descriptor set, signal table. On every process switch, the kernel saves and restores these ingredients for the individual processes. On the other hand, a thread consists of only a private program counter, stack memory, stack pointer and signal table. All other ingredients, in particular the virtual memory, it shares with the other threads of the same process.

[EDIT]

Agora fiquei na dúvida se as threads partilharam a parte da stack que já tinha sido criada quando estas são lançadas.

Não costumo usar thread em C/C++ (apenas em Java), por isso não dizer com muitas certezas como é que isto funciona.

[/EDIT]

Depende como iniciares o processo. Se for com fork(), o processo filho herda todas as variáveis e respectivos valores do processo pai até esse momento (note-se que são copias das variaveis. Não tenho a certeza como funcionam os apontadores neste caso, mas penso que o processo filho só fica com copias das coisas, por isso acho que continua a não ser possível fazer o que pretendes com o fork). Se for com uma função da familia exec*(), o processo é lançado como um novo programa sem partilharem nada.

Com o fork também não partilhas nada, no sentido em que mesmo que as variáveis estejam inicialmente com o mesmo valor, não são as mesmas variáveis.

Já agora, se usares apenas o exec* (sem um fork antes), não estás a iniciar um novo processo, estás apenas a substituir o actual.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Com o fork também não partilhas nada, no sentido em que mesmo que as variáveis estejam inicialmente com o mesmo valor, não são as mesmas variáveis.

Pois, confundi a "partilha". Esquece  :-[

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Os lugares onde as variáveis são armazenadas deve depender do compilador, assim como a forma como as threads são implementadas. Mas pelo menos quando usamos GNU Portable Threads, a stack não é partilhada.

Pelo que estudei de threads até agora, o stack (memória automática) nunca é partilhado, apenas o heap (memória dinâmica) e a memória estática. Em processos, a única forma de partilhar memória é recorrendo a APIs do sistema operativo.

Agora fiquei na dúvida se as threads partilharam a parte da stack que já tinha sido criada quando estas são lançadas.

Não, o stack não é partilhado, nem parcialmente. Só se for passado um apontador para uma variável local, o que, regra geral, não é grande ideia.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Como poderia adaptar a minha estructura de dados (1º post) de maneira a funcionar em memória partilhada? :D Depois implemento trincos ou semáforos.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Penso que não tens de adaptar as estruturas de forma nenhuma, apenas precisas de chamar as funções correctas do S.O. Podes começar por ver se isto ajuda.

Como disse, não tenho experiência nenhuma em Linux.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Substituí

if ((childpid = fork()) < 0) err_dump("server: fork error"); else if (childpid == 0) {
close(sockfd);
str_echo(newsockfd);
exit(0);}

por

if (pthread_create(&thread_id[i],NULL,str_echo, newsockfd)!=0) err_dump("Falhou a criar a thread");

e já está :)

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!


Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.


Entrar Agora