Skyon Posted May 3, 2012 at 12:17 AM Report #452846 Posted May 3, 2012 at 12:17 AM Olá pessoal, Hoje tive um teste de uma cadeira chamada Sistemas Operativos que basicamente abrange, nesta altura, multithreading/sincronização/race conditions/etc... A meio do teste, numa alínea, passei cerca de uma hora a tentar resolver o exercício de uma maneira (a maneira que supostamente está correcta), mas sem sucesso. A minha questão é: Tenho uma thread a correr, que modifica um vector (defini o vector como variável local, não sei se tería de ser feito de outra maneira) como um histograma. A ideia é a thread no final retornar o vector à main thread através de pthread_exit(&val) para o pthread_join respectivo. Como é que eu leio/imprimo os valores do array na main thread? Tentei todo o tipo de cast do valor actualizado do join mas sem sucesso. Já agora, qual é a melhor maneira de resolver este problema usando sempre um retorno de pthread_exit para pthread_join? Abraço
bsccara Posted May 3, 2012 at 12:55 AM Report #452847 Posted May 3, 2012 at 12:55 AM Um amostra do código ajudava a analisar mas uma coisa que não podes fazer é passar ponteiros para variáveis locais para fora da função. No mínimo terias de usar uma estrutura global às duas threads. Uma hipótese seria de alocares memória para o vector dentro da thread que o manipula e passar o ponteiro para esse vector através do pthread_exit. Na thread principal farias o que tivesses a fazer e libertarias a memória. Tipo: /* Estrutura para passar vector */ struct vector { int tamanho; char elementos[1]; } /* Thread 1 */ void * thread1(void * arg) { pthread_t t2; struct vector * tres; pthread_create(&t2,NULL,thread2,NULL); ... pthread_join(t2,&tres); ... free(tres,sizeof(vector) + (tres->tamanho - 1) * sizeof(char)); } /* Thread 2 */ void * thread2(void * arg) { struct vector * vec; vec = malloc(sizeof(vector) + (10 - 1) * sizeof(char)); vec->tamanho = 10; vec->elementos[0] = 'A'; vec->elementos[1] = 'K'; ... pthread_exit(vec); } Atenção que se houvesse mais pares de threads a correr em 'simultâneo' seria preciso garantir que as funções 'malloc' e 'free' seriam reentrantes, ou então controlar o acesso a elas com um objecto de sincronização. Se soubesses o tamanho do vector ao iniciar a execução da segunda thread poderias alocá-lo na primeira thread, passar o ponteiro através do último parâmetro do pthread_create e recebê-lo na segunda thread através do parâmetro da função. Para este efeito poderias usar uma variável local à thread 1.
Skyon Posted May 3, 2012 at 02:04 AM Author Report #452849 Posted May 3, 2012 at 02:04 AM Neste caso eu sabia qual seria o tamanho de vector, no entanto já passava para a thread uma estrutura como argumento. Tería de adicionar um vector à estrutura que passo à thread? Não percebi bem essa última solução que propuseste... Já agora, o apontador recebido na função join não é do tipo void? Se enviasse o endereço de um vector, como é que o poderia tratar como um vector no thread principal?
HappyHippyHippo Posted May 3, 2012 at 06:38 AM Report #452852 Posted May 3, 2012 at 06:38 AM a mim parece que pretendias mais isto : struct { int size; int * array; } Vector; void * thread_proc(void * arg) { Vector * vector = arg; ... // fazer o que se tem que fazer no vector return vector; } int main() { // thread principal Vector * vector; pthread_t thread; ... // maloc's e afins para o vector pthread_create(&t, NULL, thread_proc, vector); pthread_join(&vector); ... // imprimir os valores do vector return 0; } IRC : sim, é algo que ainda existe >> #p@p Portugol Plus
Skyon Posted May 3, 2012 at 10:34 AM Author Report #452879 Posted May 3, 2012 at 10:34 AM A variável do pthread_join não é apenas alterada pelo pthread_exit?
HappyHippyHippo Posted May 3, 2012 at 12:03 PM Report #452886 Posted May 3, 2012 at 12:03 PM desculpa... vi agora que escrevi mal o pthread_join ... seria como o bsccara fez pthread_join(thread, &vector); IRC : sim, é algo que ainda existe >> #p@p Portugol Plus
bsccara Posted May 3, 2012 at 01:22 PM Report #452891 Posted May 3, 2012 at 01:22 PM Neste caso eu sabia qual seria o tamanho de vector, no entanto já passava para a thread uma estrutura como argumento. Tería de adicionar um vector à estrutura que passo à thread? Não percebi bem essa última solução que propuseste... Poderias fazer assim : struct estrutura { int campo1; /* Inicio dos campos da tua estrutura */ int campo2; int campo3; /* Fim dos campos da tua estrutura */ char vector[100]; /* Vector de tamanho imutável */ /* ... ou ... */ int tamanho; char * vector; /* Vector de tamanho variável */ } ... struct estrutura est; pthread_t t2; ... pthread_create(&t2,NULL,thread2,&est); E na segunda thread : void * thread2(void * arg) { (struct estrutura *)arg->vector[0] = 'A'; (struct estrutura *)arg->vector[1] = 'K'; ... } Já agora, o apontador recebido na função join não é do tipo void? Se enviasse o endereço de um vector, como é que o poderia tratar como um vector no thread principal? Um ponteiro de tipo void é compatível com qualquer outro; basta fazer o typecasting para o tipo apropriado.
Skyon Posted May 4, 2012 at 12:57 AM Author Report #453010 Posted May 4, 2012 at 12:57 AM No teste era pedido explicitamente para ser obtido o vector de cada uma das threads criadas para a thread main através do join, e era essa minha duvida. Alteração de variável global contava apenas metade...
bsccara Posted May 4, 2012 at 11:18 AM Report #453039 Posted May 4, 2012 at 11:18 AM No teste era pedido explicitamente para ser obtido o vector de cada uma das threads criadas para a thread main através do join, e era essa minha duvida. Alteração de variável global contava apenas metade... Se 'vector de cada uma das threads' significa 'vector criado em cada uma das threads' então terias de fazer como indiquei no primeiro post.
Skyon Posted May 4, 2012 at 11:08 PM Author Report #453214 Posted May 4, 2012 at 11:08 PM Não é possível alocar o vector dinamicamente como um vector normal de inteiros e depois enviar o endereço pelo pthread_exit?
HappyHippyHippo Posted May 4, 2012 at 11:30 PM Report #453216 Posted May 4, 2012 at 11:30 PM foi isso que o bsccara fez !!! IRC : sim, é algo que ainda existe >> #p@p Portugol Plus
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now