Resolução de equação de segundo grau utilizando threads?
8 respostas
ccode
tinhomaranholi
Preciso criar um códgo que resolva equação de segundo grau utilizando threads. Procurando conteúdo sobre criação de threads me deparei com problema para passar as variáveis às funções threads.
Simplesmente não funciona. Alguém sabe como criar esse código? Eis o enunciado da lista:
Utilizando a linguagem C e o sistema operacional NU/Linux, desenvolva um programa que calcule as raízes, se existirem, de uma equação do segundo grau, sendo que as constantes envolvidas no cálculo deverão ser fornecidas pelo usuário via teclado. Para a resolução da equação, deve-se utilizar três processos além do processo
original. O primeiro processo será responsável por calcular o valor do delta e os demais deverão calcular as raízes da equação.
E o que você já fez?
Não sei se leu as regras do fórum, mas, não fazemos exercícios/trabalhos. Apenas ajudamos a esclarecer dúvidas específicas e pontuais a respeito de algo que você tenha construído.
tinhomaranholi
Então, eu fiz um código mas tá terrível, eu realmente não sei como fazer isso.
#include<stdio.h>#include<stdlib.h>#ionclude <pthread.h>float*calculateDelta(voida,voidb,voidc){float*a1=(float*)(a);float*b1=(float*)(b);float*c1=(float*)(c);returnpow(b1,2)-4*a1*c1;}float*calculateX1(floata,floatb,floatdelta){float*a1=(float*)(a);float*b1=(float*)(b);float*c1=(float*)(delta);return(-b1+sqrt(c1))/(2*a1);}float*calculateX2(void*a,void*b,void*delta){float*a1=(float*)(a);float*b1=(float*)(b);float*c1=(float*)(delta);return(-b1-sqrt(c1))/(2*a1);}intmain(){pthread_tx1,x2;floata=0,b=0,c=0;printf("Digite o valor de A: ");scanf("%f",&a);printf("Digite o valor de B: ");scanf("%f",&b);printf("Digite o valor de C: ");scanf("%f",&c);float*delta=pthread_create(&t1,NULL,calculateDelta,(void*)(&a,&b,&c));if(delta>0){printf("Existem duas raizes reais distintas.\n");}elseif(delta==0){printf("Existem duas raizes reais iguais.\n");}else{printf("Delta: %f, não existem raizes reais.\n",delta);return0;}floatx1=pthread_create(&t2,NULL,calculateX1,(void*)(a,b,delta));floatx2=pthread_create(&t1,NULL,calculateX2,(void*)(a,b,delta));printf("Delta: %f, X1: %f, X2: %f\n",delta,x1,x2);*/return0;}
darlan_machado
Mas não funciona?
tinhomaranholi
Não, aparecem infinitos erros. Li no Stachoverflow que parâmetros devem ser passados através de vetor. Testei:
Mas gera outro problema, pois os valores passados não são o suficiente para a realização do cálculo.
darlan_machado
Cara, precisa nada disso não, ao menos até onde eu lembro de C/C++;
Vamos lá:
Por que você passa os parâmetros para a função CalculateDelta como sendo void?
Eles não são float?
tinhomaranholi
São, mas os tutoriais que eu li quanto a passagem de parâmetros mandam passar como void.
darlan_machado
Cara, posta estes tutoriais pois eu quero me atualizar. Tudo o que aprendi em C/C++ foi por água abaixo agora.
Ainda mais quando vejo que, na função
Vocẽ usa como float.
Veja, o tipo void, até onde sei, só se usa em função, pois, ele determina que uma função não retornará nenhum valor. Como você quer calcular algo com tipo vazio?
lvbarbosa2 likes
A assinatura da função pthread_create é a seguinte:
O último parâmetro é o que lhe interessa. Ele é o ponteiro que vai ser passado para a start_routine que você passa no terceiro parâmetro.
Existem algumas formas de passar valores “compostos” para sua rotina através desse ponteiro. A forma mais simples, no seu caso, é usar uma struct.
Faz o seguinte:
Cria uma struct que carrega os 3 argumentos para sua função (a, b e c);
Crie um objeto dessa struct e preencha os 3 valores com os parâmetros;
Na chamada para pthread_create, passe a struct como void* (faça um cast explícito);
Altere as assinaturas das funções calculateX1 e calculateX2 para receber apenas um parâmetro do tipo void*;
Dentro dessas funções, você vai fazer outro cast explícito de void* para a sua struct com os parâmetros;
Extraia os valores de a, b e c da struct e faça a conta que tiver que fazer.
A função pthread_createnão retorna o valor da função que você passa por parâmetro para ela.
Por isso x1 e x2 não vão ter o valor retornado pelas funções.
Você precisa colocar um outro valor dentro da struct, chamado resultado (ou algo assim). É nesse valor que as funções vão escrever o resultado final do cálculo. O problema é que você não pode acessar esse valor assim que fizer as chamadas para pthread_create, pois existe uma condição de corrida onde a thread principal pode tentar acessar os resultados antes das funções terem os escrito nas structs. Você pode resolver essa condição com um semáforo.
Outra forma de capturar o retorno das threads é usando as funções pthread_exit e pthread_join.
É difícil explicar essas coisa num post curto. Para resolver esse exercício você precisa entender muito bem como funcionam ponteiros, casting e o tipo genérico void*.
Boa sorte.
Fiz um exemplo para te ajudar a começar. Entenda e extrapole pro seu caso.