Ajuda com Python - Urgente

Nelson Pires

Power Member
Boa noite,

Estou com um problema a correr código na máquina virtual (linux).

O código consiste num pipe em que o "pai" envia uma mensagem e o "filho" recebe-a e escreve o que recebe que neste caso é um número random que calhou ao "pai".

O que acontece é que só por vezes (muito raramente e a insistir muito) é que o filho recebe a "mensagem" na máquina virtual.

O código é o seguinte:

\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
import os
import random

num = random.randint(0,100)
nomepipe = 'number_prime'

if not os.path.exists(nomepipe):
os.mkfifo('nomepipe')

def filho():
pipei = open(nomepipe,'r')
mensagem = pipei.readline()
print ("Recebi", mensagem)
res = is_prime(num)
print(res)

def pai():
s=str(num)
pipei = open(nomepipe, 'w')
pipei.write(s)
print ("o pai enviou ",s)


def is_prime(n):
'''check if integer n is a prime'''
# make sure n is a positive integer
n = abs(int(n))
# 0 and 1 are not primes
if n < 2:
return False
# 2 is the only even prime number
if n == 2:
return True
# all other even numbers are not primes
if not n & 1:
return False
# range starts with 3 and only needs to go up
# the square root of n for all odd numbers
for x in range(3, int(n ** 0.5) + 1, 2):
if n % x == 0:
return False

return True


pid = os.fork()
if pid != 0:
pai()
else:
filho()



\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\



Resultado na máquina virtual:

nelson@debian:~$ python3 exercicio1.py
o pai enviou 33
Recebi

nelson@debian:~$ python3 exercicio1.py
o pai enviou 89
Recebi

nelson@debian:~$ python3 exercicio1.py
o pai enviou 23
Recebi

nelson@debian:~$ python3 exercicio1.py
o pai enviou 63 ------------> só aqui é que mostra a mensagem que o filho recebeu
Recebi 63


nelson@debian:~$ python3 exercicio1.py
o pai enviou 33
Recebi

...
...






Já enviei o ficheiro para uns colegas meus e nas máquinas deles funciona perfeitamente, apenas no meu é que acontece isto. Até perguntei ao meu stor e ele também não encontrou a solução.


Peço desculpa se não me expressei bem, mas tentei fazer o melhor possível para perceberem a minha situação...

Obrigado
 
Última edição:
O teu professor não encontrou a solução? Mas que curso estás a tirar?!? Professor de quê?

1º Tens 2 processos a correr em paralelo, logo convém teres um semáforo...
2º Tens coisas em português e coisas em inglês, tenta ter todo o código e comentários em inglês, mesmo que os prints sejam em português.
3º Convém esperar pelo filho... sem o wait podes simplesmente acabar antes do filho.

Código:
import os
import random
from multiprocessing import Lock, Semaphore

num = random.randint(0,100)
nomepipe = 'number_prime'
mfather = Lock() // Mutex started as open
mson = Semaphore(0) // Semaphore started with counter as 0 (locked)

if not os.path.exists(nomepipe):
   os.mkfifo('nomepipe')

def son():
   mson.acquire() # try to get access to semaphore son (started as locked/0)
   pipei = open(nomepipe,'r')
   mensagem = pipei.readline()
   pipei.close()
   mfather.release() # After reading file, unlock father for new one to enter in the mutex
   print ("Recebi", mensagem)
   res = is_prime(num)
   print(res)

def father():
   mfather.acquire() # try to get access to the mutex father (started as unlocked)
   s=str(num)
   pipei = open(nomepipe, 'w')
   pipei.write(s)
   pipei.close()
   print ("o pai enviou ",s)
   mson.release() # After writing to file, unlock son semaphore, 1 son can enter


def is_prime(n):
   '''check if integer n is a prime'''
   # make sure n is a positive integer
   n = abs(int(n))
   # 0 and 1 are not primes
   if n < 2:
     return False
   # 2 is the only even prime number
   if n == 2:
     return True
   # all other even numbers are not primes
   if not n & 1:
     return False
   # range starts with 3 and only needs to go up
   # the square root of n for all odd numbers
   for x in range(3, int(n ** 0.5) + 1, 2):
     if n % x == 0:
       return False
   return True


pid = os.fork()
if pid == 0: # pid is 0 when is son
   son()
else: # process who did fork will have the sons process id
   father()
   os.wait() # i'm the father, i need to wait for the sons, it will work with multiple sons
 
Última edição:
O teu professor não encontrou a solução? Mas que curso estás a tirar?!? Professor de quê?

1º Tens 2 processos a correr em paralelo, logo convém teres um semáforo...
2º Tens coisas em português e coisas em inglês, tenta ter todo o código e comentários em inglês, mesmo que os prints sejam em português.
3º Convém esperar pelo filho... sem o wait podes simplesmente acabar antes do filho.

[/code]

A funcionar!!!!

Ele simplesmente esteve 5 minutos a olhar para o meu código a ver o que poderia estar errado, não encontrou nada e desistiu. O que ele me disse não foi nada menos que "não te sei dizer o que é que está a passar".
Ao mesmo tempo percebia-o porque nos portáteis dos meus colegas o mesmo código corria bem sem problema. Sabes-me explicar o porque? Desinstalei e voltei a intalar o VMware, o debian 8 e mesmo assim continuava igual.

O professor é de Sistemas Operativos, estou a tirar Informática.

Antes de mais obrigado pelas dicas!! Lembro-me de nas primeiras aulas termos falado nos semáforos e etc. mas por incrível que pareça foi ele (o professor) que escreveu o código no quadro para nos servir de base para fazer uns exercícios que ele nos tinha pedido.
 
A funcionar!!!!

Ele simplesmente esteve 5 minutos a olhar para o meu código a ver o que poderia estar errado, não encontrou nada e desistiu. O que ele me disse não foi nada menos que "não te sei dizer o que é que está a passar".
Ao mesmo tempo percebia-o porque nos portáteis dos meus colegas o mesmo código corria bem sem problema. Sabes-me explicar o porque? Desinstalei e voltei a intalar o VMware, o debian 8 e mesmo assim continuava igual.

O professor é de Sistemas Operativos, estou a tirar Informática.

Antes de mais obrigado pelas dicas!! Lembro-me de nas primeiras aulas termos falado nos semáforos e etc. mas por incrível que pareça foi ele (o professor) que escreveu o código no quadro para nos servir de base para fazer uns exercícios que ele nos tinha pedido.
Engenharia Informática? Onde?

Nunca vi dar Sistemas Operativos em Python, mas os semáforos é uma das matérias mais importantes de Sistemas Operativos e é obrigatório saber, para garantir que não era só eu a implicar com o teu professor, dei o problema a um colega meu e dei-lhe os tais 5 minutos para encontrar o problema e ele encontrou...

Explicar problemas de concorrência é fácil com um quadro onde podes exemplificar, por texto pode ficar um pouco confuso, mas vou tentar.

Quando lanças 2 processos/tarefas eles vão concorrer entre si, se só houver um core/processador só vai correr uma tarefa de cada vez, por exemplo o filho corre uma linha de código, perde o processador para o pai que corre mais uma linha e volta a perder o processador para o filho que corre 2 linhas e depois perde o processador para o pai, sempre assim, nunca correm os 2 ao mesmo tempo.
Isto devias dar em Sistemas Operativos, normalmente serve como projecto para aplicar num kernel, porque é o kernel que decide quem perde o processador para quem.

Como podes ver, processadores ou kernels diferentes faz com que a concorrência seja efectuada de modo diferente, e por isso funcionar nalguns e noutros não.
 
Engenharia Informática? Onde?

Em Coimbra, não vou dizer onde exatamente para não gerar complicações, como podes perceber.

E sim, estou a dar Python em SO. Estou no 2º ano de informática.
É uma pena quando existem professores que apenas exercem a profissão pelos €€€ e não pelo gosto de ensinar... just saying.
 
Podes aprender SO aqui: https://www.ops-class.org/slides/

Mas a cadeira é dada por aulas teóricas e práticas, certo? Há universidades em que permitem que alunos de doutoramento ou mestrado possam dar aulas práticas de cadeiras de licenciatura, no entanto para ser regente é preciso ter doutoramento, agora o professor que deu esse exemplo é o regente? É doutorado?

Já encontrei muitos professores maus, que sabiam menos que muitos alunos, mas a cadeira de sistemas operativos é muito importante e não devia ser dado por qualquer um, eu não a daria.

Entretanto eu adicionei alguns comentários, se tiveres alguma dúvida avisa.
 
Podes aprender SO aqui: https://www.ops-class.org/slides/

Mas a cadeira é dada por aulas teóricas e práticas, certo? Há universidades em que permitem que alunos de doutoramento ou mestrado possam dar aulas práticas de cadeiras de licenciatura, no entanto para ser regente é preciso ter doutoramento, agora o professor que deu esse exemplo é o regente? É doutorado?

Sim, a cadeira é dada numa aula de 4h seguidas por semana e é dividida em teórica e prática. Julgo que ele seja doutorado mas não te sei dizer ao certo, já é uma pessoa com os seus 35 anos (apesar de isto não querer dizer nada).

Tive outro prof que se imaginasses como eram dadas as aulas por ele de programação no 1ºano, uiiii... até caias para o lado. Uma pessoa extremamente introvertida e ainda pra mais percebia muito pouco de programação. Nós andávamos a meio do ano sem saber fazer um simples ArrayList ou um while. Então quando ele explicava alguma coisa ou algum exercício no quadro aquilo era demais, Apaga-Escreve-Apaga-Escreve-Apaga-Escreve sempre continuamente, ele era capaz de estar praticamente metade da aula nisto para resolver um exercício, mas estou a falar de exercícios bastante simples de fazer e até de explicar.
Infelizmente estou a ter com ele, este semestre, Estrutura de Dados e Algoritmos...

Sim, eu já percebi que vamo-nos ver aflitos com SO. Ou fazemos muita pesquisa em casa e treinamos ou então vai ser um cadeirão daqueles...

Obrigado pela referência dos Slides, vou passá-los também para os meu colegas para ver se começamos todos a encalhar com isto.

Em relação aos semáforos já consigo dar a volta à coisa, é até intuitivo e percebe-se bem.
Na próxima aula vou-lhe mostrar para ver o que é que ele diz.
 
Back
Topo