Ir ao conteúdo
  • Cadastre-se

Programação paralela


mcirqueira

Posts recomendados

Olá boa tarde !

Eu presciso escrever um programa que ler um arquivo contendo nomes de pessoas e que teria que enumerar depois do nome, tipo:

maria

joão

jose 

e respectivamente

maria 1

joão 2

jose 3.

 

Mas o arquivo é grande e eu queria implementar um codigo que usaria 2 threads, uma percorrendo do inicio ate a metade e outra do final  ate a metade, e escrevendo o resultado em um vetor de caracteres global.

Atualmente estou estudando threads, mas as informações que acho são muito simples, com funções pthread_create pthread_join e pthread_exit, mas gostaria de me aprofundar mais, com outras funções da biblioteca pthreads e funções de sincronismo. Alguem tem um bom material para eu estudar a respeito ?

Link para o comentário
Compartilhar em outros sites

4 horas atrás, vangodp disse:

Não entendo bem o que você quer fazer... você quer por um numero ao lado de cada nome é isso? Ou você quer organizar os nomes?

 

E só por um numero, e quanto as threads, eu n achei nenhum conteúdo que explanasse sobre outras funçoes como pthread_cond_signal(), pthread_cond_wait(), pthread_cond_broadcast(), pthread_attr_init(), pthread_attr_setstacksize() e etc. Saca ?

Nas man pages tem tudo isso, mas elas não são muitos claras, são mais uma referencia

Link para o comentário
Compartilhar em outros sites

Olá!

 

 

 

Oi, sou inciante em C, sem contar que por hora estou parado na linguagem, mas a alguns meses atrás quando mais ativo busquei uma serie de links que talvez me pudessem ser uteis no futuro . . .

 

 

Bom a maior parte dos links nada mais vai ser do que mais do mais do que você provavelmente já sabe, além de que a maioria esmagadora é em inglês, mas de todo modo:

 

 

 

Este é um dos que acho mais bem detalhados ao meu ver, fala o que acredito ser o mais próximo do que você já sabe, sem contar que tem uma referencia no final da pagina sobre os principais comandos e funções da biblioteca:

 

https://computing.llnl.gov/tutorials/pthreads/

 

 

 

Este link em inglês traz uma breve explicação básica sobre pthreads, porém possui no final da pagina algumas descrições básicas sobre alguns dos comandos e funções da biblioteca:

 

http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html

 

 

 

Este Link é a mesma coisa, usando inclusive como referencia os links de descrição de comandos e funções do link anterior:

 

http://www.cs.cmu.edu/afs/cs/academic/class/15492-f07/www/pthreads.html

 

 

 

Também tem este link que possui dois PDFs, o primeiro é em português enquanto que o segundo em Inglês:

 

http://www.cin.ufpe.br/~rngs/Arquivos/pthreads/

 

 

 

Obs.: apenas atente para o fato de que não tenho certeza se os links que lhe passei acima podem ser uteis para o sistema que você usa, mas de todo modo acho que lhe dá alguma luz.

 

 

 

Bom por hora é só, apenas lembrando que sou inciante em C, não tenho nenhum conhecimento sobre threads e que estou parado a algum tempo . . .

 

 

 

 

Ubuntu 14.04 GCC 4.8 CodeBlocks 13.12

 

 

 

 

Espero Ter Ajudado ! ! !

Link para o comentário
Compartilhar em outros sites

Valeu @FelipePetropolis, vou dar uma olhada.

Quanto ao prototipo, escrevi isso ontem e ainda n tive tempo de compilar, mas deve funcionar.

Ainda ta na fase de ler o arquivo e separar as palavras como membros de um vetor bidimensional para que eu possa trabalhar com as palavras individualmente.

 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main () {
	FILE *arq;
	
//		100 palavras de 255 caracteres
	char buffer[100][255];
	// buffer de leitura
	char buf[10];
	char nome[255];
	// buffer de linha atual
	char linha[255];
	size_t sz;
	// onde sera armazenado o conteudo do arquivo lido
	char arquivo_original[9999];

	printf("Digite o nome do arquivo: ");
	scanf("%254s", &nome);

	arq = fopen(nome, "r");
	
	if(arq == NULL) {
		perror("fopen");
		exit(1);
	}

	while(!feof(arq))
	{
	
		sz = fread((void *) buf, 9, 1, arq);
		buf[9] = '\0';
		strcat((void *) &arquivo_original,(void *) &buf);

	}
	
 	printf("Conteudo: \n");

	printf("%s\n", arquivo_original);	

	register int x;
	register int y = 0;

	//percorre o conteudo do arquivo lido
	for(x = 0; x<= strlen(arquivo_original); x++)
	{
		/* enquanto posição x diferente de \n, caractere x de linha
		 * igual a caractere x de arquivo_original */
		if(arquivo_original[x] != "\n")
		{
			linha[x] = arquivo_original[x];
		} else 
		{
			// incrementa posição y
			y++;
			linha[strlen(linha) - 1] = "\0";
		}
		// copia a linha pra sua posição correspondente no vetor
		strcpy(&buffer[x][y], &linha);
	}

	printf("\n");
	fclose(arq);

	return 0;
} // main

 

Depois que eu me certificar que esta funcionando, vou fazer uma função e criar 2 threads e ver se funciona.

Achei também esse arquivo, muito bom e pode lhe ser útil também: http://www2.dc.ufscar.br/~hermes/FITEM2010/2.FITEM-Pthreads.pdf

Link para o comentário
Compartilhar em outros sites

Vejo varios problemas ao tentar implementar threads para esse algoritimo. Primeiro você ja tentou trabalhar com mais de um ponteiro por arquivo? Prove criar dois filepointer e escrever frases tipo usando o ponteiroA "ptr1 linha1", e depois usando o ponteiroB "ptr2 linha2" e logo volte a usar o ponteiroA "ptr1 linha3". O código te deixo abaixo:
 

#include <stdio.h>
#include <stdlib.h>

int main (){
    
    FILE *a=fopen("prova.txt", "w");
    FILE *b=fopen("prova.txt", "w");
    
    fprintf(a,"linha1\n");
    fprintf(b,"linha2\n");
    fprintf(a,"linha3\n");
    
    fclose(a);
    fclose(b);
    getchar();
    return 0;
}

O problema é que um apontador vai ficar trepando em cima do outro. Tudo bem.. para operação de leitura não tem muito problema, você pega 1 ponteiro encontra a metade do arquivo, leva o segundo ponteiro lá, e precisa também de um contador para saber exatamente qual a metade do arquivo, para poder ir contando desde aí com o ptr2, ou com o mesmo ponteiro você pode ir até a metade e começar a marcar desde aí. O problema é que acho que você não vai ganhar muito em rendimento, pois você tem 2 ponteiros, a um arquivo mas o disco duro só tem acesso a um deles por vez, com 2 ponteiros acho que o único que você vai conseguir é fazer o disco ir de um lado para outro perdendo rendimento, deveria ser feita provas de rendimento com um ou dois ponteiros a ver se realmente tem ganancia no que a rendimento se refere, não se esqueça que o disco trabalha mais rápido se o acesso é seqüencial, ele é mais rápido quanto menos mover a agulha magnética. A mesma coisa acontece com a memória RAM, o tempo que você demora em acessar  uma posição da memória e mudar a outra se traduz em perda de rendimento, busque sempre dar o menor numero de saltos possíveis.
Só falo tudo isso que por mais que você usar threads, ao se tratar de acesso ao disco duro, possivelmente você não vai ver um incremento tão significativo, os threads se usam para paralelismo, quando você precisa deter uma coisa e passar a seguinte coisa, mas fazendo uma analogia, se você for um garçom, e alguém te pedir um prato de queijo, você pega a faca e corta o queijo, ai outra pessoa pede um prato de sopa, ai você solta a faca e pega a concha de sopa, ai cada um que entrar pede desse modo alternando, queijo e sopa, esse tempo que você leva para trocar de faca para concha, de concha para faca é uma perda de tempo considerável. Não seria mais rápido primeiro servir todos os queijos e depois todas as sopas? Pense nisso... Ao trocar de faca a concha você perde tempo, mas ao servir primeiro queijo e depois sopa você só troca de ferramenta uma única vez, isso é rendimento assegurado. >_<

Sorte! Continue informando como vai seu programa, trata-se de um tema curioso como mínimo.

Link para o comentário
Compartilhar em outros sites

Ok @vangodp ,

desculpe a demora, mas e que eu trabalho de segunda a quinta em um predio e sexta no outro, so tenho acesso a internet quando estou no 1º predio.

 

O codigo que fiz primeiramente tava meio podre k, fiz algumas modificações, mas to com uns probleminhas logo na parte de tratar cada palavra(linha) separadamente.

O contador eu tava pensando em, como ja tenho uma variavel para armazenar o conteudo do arquivo lido, ia usar strlen(buffer) / 2 para indicar a metade.

No meu pc eu uso 3 hds, como minha cpu e um dual core, 2 threads e dividir o arquivo em 2 acho ajudaria.]

Vou baixar um compilador aqui e terminar umas coisas e posto o codigo.

Link para o comentário
Compartilhar em outros sites

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define TAM        1024000
#define TAM_READ      4096

int main () 
{
	FILE *arq;
	
//		3000 palavras de 255 caracteres
	char buffer[3000][255];
	// buffer de leitura
	char buf[4096];
	char nome[255];
	// buffer de linha atual
	char linha[255];
	// onde sera armazenado o conteudo do arquivo lido
	char arquivo_original[TAM];

	printf("Digite o nome do arquivo: ");
	scanf("%254s", &nome);

	arq = fopen(nome, "r");
	
	if(arq == NULL) {
		perror("fopen");
		exit(1);
	}

	while(!feof(arq))
	{
	
		fread((char *)&buf, TAM_READ, 1, arq);
		strcat(arquivo_original, buf);
		memset(buf, 0, TAM_READ);

	}

	arquivo_original[strlen(arquivo_original) - 1] = '\0';

	printf("Tamanho: %d caracteres\n", strlen(arquivo_original));
 	printf("Conteudo: \n%s\n", arquivo_original);	
	
	register int x;
	register int y = 0;

	//percorre o conteudo do arquivo lido
	for(x = 0; x < (strlen(arquivo_original) + 1); x++)
	{		
		if(arquivo_original[x] == '\n')
		{
			y++;
			strcpy(buffer[y], linha);
			memset(linha, 0, 255);
		} else
		{
			strcat(linha, (char *)arquivo_original[x]);
		}	
	}

	// A parte abaixo funciona, mas o for da segmentation fault
	/*strcpy(buffer[0], "joao");
	strcpy(buffer[1], "maria");
	strcpy(buffer[2], "garibaldo");
	strcpy(buffer[3], "raimundo");
	strcpy(buffer[4], "marcos");
	strcpy(buffer[5], "conceicao");
	strcpy(buffer[6], "silvana");
	strcpy(buffer[7], "fernanda");
	strcpy(buffer[8], "estalony");*/
	
	printf("Conteudo do buffer: \n");
	for(x = 0; x < (strlen(buffer[x]) + 1); x++)
	{
		printf("Linha %d: ", x);	
		printf("%s\n", buffer[x]);
	}

	printf("\n");
	fclose(arq);

	return 0;
} // main

O for esta dando segmentation fault n sei porque, eu tambem estava pensando em colocar alocação dinamica para o vertor buffer[][], mas so sei implementar isso com vetores unidimensionais.

Link para o comentário
Compartilhar em outros sites

//percorre o conteudo do arquivo lido 
	for(x = 0; x < (strlen(arquivo_original) + 1); x++)
	{		
		if(arquivo_original[x] == '\n')
		{
			y++;
			linha[strlen(linha) + 1] = '\0';
			strcpy(buffer[y], linha);
			memset(linha, 0, 255);
		} else 
		{
			//strcat(linha, (char *)arquivo_original[x]);
			//strcpy(linha[x], (char *)arquivo_original[x]);
			linha[x] = arquivo_original[x];
		}
		
	}

Na parte do else, tanto o strcat quanto o strcpy dão erro (segmentation fault (linux) ou para de funcionar (windows)), apenas o que não esta comentado que funciona, mas guarda somente a primeira linha do arquivo e imprime:

Conteudo do Buffer:

Linha 0:

Linha 1: joao

 

Link para o comentário
Compartilhar em outros sites

Fiz algumas modificações no codigo e to adaptando ele pra processamento paralelo agora

 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>

#define TAM        1024000
#define TAM_BUFFER    4096
#define NUM_THREADS      2

#define PALAVRAS       300
#define QUANTI         255

//		300 palavras de 255 caracteres
char buffer[PALAVRAS][QUANTI];
char buf1[255], buf2[255];
int numero_caracteres;

FILE *out1, *out2;

void * contador (void *sig)
{
	int *sinal = (int *)sig;

	// Como saber quantas posições 'x' do buffer[x][y] foram ocupadas ?
	register int tamanho;
	register int i;

	// Assim esta certo ?
	for (i = 0; i < PALAVRAS; i++)
	{
		if (buffer[i] == '\0') break;
		else tamanho++;
	}

	// Aki esta tudo certo ou alguma melhoria ?
	if (*sinal == 0)
	{
		out1 = fopen(buf1, "a");
		// +128, caso ultrapasse 4096, 128 de reserva
		char buf_write[TAM_BUFFER + 128];
		char temp[255];

		for (i = 0; i < (tamanho / 2); i++)
		{
			/* Se igual a 4kb, escreve no arquivo
			 * Para evitar multiplas system calls, buffer
			 * pra reduzir chamadas e melhorar desempenho
			 */
			if ((strlen(buf_write)) >= (TAM_BUFFER - 128))
			{
				fprintf(out1, "%s", buf_write);
				memset(buf_write, 0, (TAM_BUFFER + 128));
			}
			// Formata string
			sprintf(temp, "%d: %s\n", i, buffer[i]);
			// Concatena no buffer
			strcat(buf_write, temp);
		}

		fclose(out1);
	} //thread 1
	else
	{
		out2 = fopen(buf2, "a");
		// +128, caso ultrapasse 4096, 128 de reserva
		char buf_write[TAM_BUFFER];
		char temp[255];

		for (i = (tamanho / 2); i < tamanho; i++)
		{
			/* Se igual a 4kb, escreve no arquivo
			 * Para evitar multiplas system calls, buffer
			 * pra reduzir chamadas e melhorar desempenho
			 */
			if ((strlen(buf_write)) >= (TAM_BUFFER - 128))
			{
				fprintf(out2, "%s", buf_write);
				memset(buf_write, 0, (TAM_BUFFER + 128));
			}
			
			sprintf(temp, "%d: %s\n", i, buffer[i]);
			strcat(buf_write, temp);
		}

		fclose(out2);
	}// thread 2

	return NULL;
} // contador

void usage (char nome[255])
{
	printf("Use o formato %s input output1 output2\n", nome);
}

int main (int argc, char *argv[])
{
	FILE *arq;
	pthread_t th[NUM_THREADS];
	int a;
	int ret[NUM_THREADS];

	for (a = 0; a < NUM_THREADS; a++)
	{
		ret[a] = pthread_create(&th[a], NULL, contador, (void *) a);

		if(ret[a] != 0) printf("Erro na criacao da thread %d!\n", a);

	}

	char buf[TAM_BUFFER];
	char nome[255];
	char linha[255];
	char arquivo_original[TAM];

	if (argc < 4)
	{
		usage(argv[0]);
		exit(0);
	}

	// Nome do arquivo de entrada
	strcpy(nome, argv[1]);
	// Nome dos de saida
	strcpy(buf1, argv[2]);
	strcpy(buf2, argv[3]);

	arq = fopen(nome, "r");
	
	if(arq == NULL) 
	{
		perror("fopen");
		exit(1);
	}

	while(!feof(arq))
	{
	
		fread((char *)&buf, TAM_BUFFER, 1, arq);
		strcat(arquivo_original, buf);
		memset(buf, 0, TAM_BUFFER);

	}

	numero_caracteres = strlen(arquivo_original) + 1;
	arquivo_original[numero_caracteres - 2] = '\0';

	printf("Tamanho do arquivo: %d caracteres\n", numero_caracteres);
 	printf("Conteudo: \n%s\n", arquivo_original);	
	
	register int x;
	register int y = 0;

	
	for(x = 0; x < numero_caracteres; x++)
	{		
		if(arquivo_original[x] == '\n')
		{
			linha[strlen(linha) + 1] = '\0';
			strcpy(buffer[y], linha);
			memset(linha, 0, 255);
			y++;							
		} else 
		{
			//strcat(linha, (char *)arquivo_original[x]);
			//strcpy(linha[x], (char *)arquivo_original[x]);
			linha[x] = arquivo_original[x];
		}		
	}

	// A parte abaixo funciona, mas o for da segmentation fault
/*	strcpy(buffer[0], "joao");
	strcpy(buffer[1], "maria");
	strcpy(buffer[2], "garibaldo");
	strcpy(buffer[3], "raimundo");
	strcpy(buffer[4], "marcos");
	strcpy(buffer[5], "conceicao");
	strcpy(buffer[6], "silvana");
	strcpy(buffer[7], "fernanda");
	strcpy(buffer[8], "estalony");
	strcpy(buffer[9], "jhonanta");
*/


	printf("Conteudo do buffer: \n");
	// Como saber quantas palavras estão ocupando o buffer[][] ?
	// Quantas posições 'x' do buffer[x][y] estao em uso ?
	for(x = 0; x < 10; x++)
	{
		printf("Linha %d: ", x);	
		printf("%s\n", buffer[x]);
	}

	printf("\n");
	fclose(arq);

	return 0;
} // main

 

 

Quando eu coloco algum codigo no forum fica sem a syntax highlighting

Link para o comentário
Compartilhar em outros sites

  • 2 semanas depois...
Visitante
Este tópico está impedido de receber novas respostas.

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...

 

GRÁTIS: ebook Redes Wi-Fi – 2ª Edição

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!