C/Visual C - primos mediante espera activa con hebras

 
Vista:
sin imagen de perfil
Val: 5
Ha aumentado su posición en 15 puestos en C/Visual C (en relación al último mes)
Gráfica de C/Visual C

primos mediante espera activa con hebras

Publicado por bart (3 intervenciones) el 08/01/2020 17:02:13
hola, tengo este problema que no consigo resolver.Implementar un programa que obtenga M números primos utilizando 2 hebras trabajadoras y una coordinadora. Cuando una trabajadora está desocupada "pide” un número a la coordinadora. Si comprueba que es primo lo añade a un array compartido con la otra hebra trabajadora, en otro caso lo descarta. Cuando se hayan calculado los M números primos el programa debe acabar y mostrar por pantalla los números primos obtenidos.
gracias por su ayuda.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#include <pthread.h>
#include <stdio.h>
#define M 10
#define tr 0
#define co 1
 
 
int array[M];
int num;
int fin=0;
int haynum=0;
 
int turnoTR=0;
int turnoTR_C=0;
 
int fTR[2]={0,0};
int fTR_C[2]={0,0};
 
int esprimo(int p){
	int i,cnt=0;
	for(i=1;i<=p;i++){
		if(p%i==0){
			cnt++;
		}
 
	}
 
	if(cnt==2)
	return 1;
	else
	return 0;
}
 
void *primo(void *argg){
	 int i=0,cnt=0;
	 int id=*(int *)argg;
	 int otro=(id+1)%2;
 
	 while(!fin){
		 // peterson entre trabajadoras
		 fTR[id]=1;
		 turnoTR=otro;
		 while(fTR[otro] && turnoTR==otro);
		 //peterson entre la trabajadora y la coordinadora
		 fTR_C[tr]=1;
		 turnoTR_C=co;
		 while(fTR_C[co] && turnoTR_C==co);
 
		 // seccion critica
		 if(esprimo(num)){
			array[i]=num;
			i++;
			cnt++;
 
		 }
		 if(cnt==M){
		    fin=1;
		 }
		 haynum=0;
		 fTR_C[tr]=0;
		 fTR[id]=0;
 
	 }
 
	 pthread_exit(NULL);
 
}
 
void *gen(void *argg){
	int i=2;
 
	while(!fin)){
 
		fTR_C[co]=1;
		turnoTR_C=tr;
		while(fTR_C[tr] && turnoTR_C==tr);
		if(!haynum){
		num=i;
		i++;
		haynum=1;
	    }
 
 
        fTR_C[co]=0;
 
 
	}
	pthread_exit(NULL);
 
}
 
 
 
 
int main(){
	int i,id[2];
	pthread_t tra[2],coor;
 
	for(i=0;i<2;i++){
		id[i]=i;
	  pthread_create(&tra[i],NULL,primo,&id[i]);
 
    }
 
	pthread_create(&coor,NULL,gen,NULL);
 
	for(i=0;i<2;i++){
 
	  pthread_join(tra[i],NULL);
 
    }
 
	  pthread_join(coor,NULL);
 
	for(i=0;i<M;i++){
		printf(" %d ",array[i]);
	}
}
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder

primos mediante espera activa con hebras

Publicado por Tom (619 intervenciones) el 09/01/2020 13:05:06
Prueba esto.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <pthread.h>
 
#define TARGET_COUNT 10
int numbers[TARGET_COUNT] = {-1};
pthread_mutex_t numbers_lock = PTHREAD_MUTEX_INITIALIZER;
int pfd[2] = {-1, -1};
 
/* */
static void insert_number(int v) {
	if(v >= 0 && v < TARGET_COUNT) {
		pthread_mutex_lock(&numbers_lock);
		numbers[v] = v;
		printf(" Inserted value %d\n", v);
		pthread_mutex_unlock(&numbers_lock);
	}
}
/* */
static void* t_start(void *data) {
	int id = (int)data;
	int val;
 
	while(read(pfd[0], &val, sizeof(val)) > 0) {
		printf("Thr %d reads %d\n", id, val);
		insert_number(val);
	}
	pthread_exit(0);
}
/* */
int main(int argc, char *argv[]) {
	if(pipe(pfd) < 0) {
		perror("pipe");
		exit(1);
	}
	pthread_t thrs[2];
	pthread_attr_t attrs;
 
	pthread_attr_init(&attrs);
	for(int i = 0; i < 2; i++) {
		pthread_create(&thrs[i], &attrs, t_start, (void*)i);
	}
 
	for(int i = 0; i < TARGET_COUNT; i++) {
		write(pfd[1], &i, sizeof(i));
	}
	close(pfd[1]);
	pthread_join(thrs[0], NULL);
	pthread_join(thrs[1], NULL);
}
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil
Val: 5
Ha aumentado su posición en 15 puestos en C/Visual C (en relación al último mes)
Gráfica de C/Visual C

primos mediante espera activa con hebras

Publicado por bart (3 intervenciones) el 09/01/2020 14:55:40
Muchas Gracias por tu respuesta. El problema es que la solucion debe ser con espera activa o sea que debo usar ni mutex ni semaforos.
tambien usaste pipes que sera paso por mensaje (creo) que debe ser a traves de una variable global compartida.
se que metodoas mas faciles para resolverlo pero debo entender primero como funciona el algorithmo con espera activa.

saludos
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

primos mediante espera activa con hebras

Publicado por Tom (619 intervenciones) el 09/01/2020 15:25:39
He puesto ese código porque eres muy poco concreto en tu cuestión originalmente y hay bastantes posibles soluciones.

Por ejemplo, así puedes usar un mutex con espera activa:
1
2
3
4
5
6
7
8
9
/* */
static void insert_number(int v) {
	if(v >= 0 && v < TARGET_COUNT) {
		while(pthread_mutex_trylock(&numbers_lock) != 0);
		numbers[v] = v;
		printf(" Inserted value %d\n", v);
		pthread_mutex_unlock(&numbers_lock);
	}
}
Tambien puedes usar pthread_spin_lock() que es específicamente para "busy-waiting"
Y además, puedes usar, con todos sus problemas "ocultos" la forma más simple de ejemplo:

https://en.wikipedia.org/wiki/Busy_waiting
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

primos mediante espera activa con hebras

Publicado por Tom (619 intervenciones) el 09/01/2020 20:45:02
Separa tu problema en dos partes, ya que cada una tendrá un enfoque diferente.
Esta es una posible solución a la primera parte, sin garantías de que funcione siempre correctamente (por cierto, lo que tu llamas "forma fácil" es en realidad la forma para que funcionen estas cosas).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <stdbool.h>
#include <stdio.h>
 
#define THR_COUNT 2
#define MAX_VALUES 20
 
struct PDATA {
	pthread_t thr;
	int id;
	int value;
	bool produced, requested;
} threads[THR_COUNT] = {0};
bool finish = false;
 
/* */
void* t_start(void *user) {
	struct PDATA *data = (struct PDATA*)user;
 
	while(!finish) {
		data->requested = true;
		while(!data->produced);
		printf("Thr %d gets %d\n", data->id, data->value);
		data->produced = false;
	}
	pthread_exit(0);
}
/* */
int main(int argc, char *argv[]) {
	int cur_val = 0;
	pthread_attr_t attrs;
 
	pthread_attr_init(&attrs);
	for(int i = 0; i < THR_COUNT; i++) {
		threads[i].id = i;
		threads[i].value = -1;
		threads[i].requested = false;
		threads[i].produced = false;
		pthread_create(&threads[i].thr, &attrs, t_start, &threads[i]);
	}
 
	while(!finish) {
		for(int i = 0; i < THR_COUNT; i++) {
			if(threads[i].requested && !threads[i].produced) {
				threads[i].produced = true;
				threads[i].value = cur_val++;
				threads[i].requested = false;
 
				if(cur_val == MAX_VALUES) {
					finish = true;
					break;
				}
			}
		}
	}
 
	for(int i = 0; i < THR_COUNT; i++) {
		pthread_join(threads[i].thr, NULL);
	}
}
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil
Val: 5
Ha aumentado su posición en 15 puestos en C/Visual C (en relación al último mes)
Gráfica de C/Visual C

Numeros primos mediante espera activa con el metodo de Peterson

Publicado por Bart (3 intervenciones) el 10/01/2020 15:23:03
Gracias otra vez por la respuesta. hice unos pocos ajustes a mi codigo y ahora funciona. Espera activa con el metodo de peterson.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#include <pthread.h>
#include <stdio.h>
#define M 10
#define tr 0
#define co 1
 
 
int array[M];
int num=-1;
int fin=0;
 
int cnt=0;
int turnoTR=0;
int turnoTR_C=0;
 
int fTR[2]={0,0};
int fTR_C[2]={0,0};
 
int esprimo(int p){
	int i,cont=0;
	for(i=1;i<=p;i++){
		if(p%i==0){
			cont++;
		}
	}
	if(cont==2)
	return 1;
	else
	return 0;
}
 
void *primo(void *argg){
 
	 int id=*(int *)argg;
	 int otro=(id+1)%2;
 
	 while(!fin){
		 // peterson entre trabajadoras
		 fTR[id]=1;
		 turnoTR=otro;
		 while(fTR[otro] && turnoTR==otro);
		 //peterson entre la trabajadora y la coordinadora
		 fTR_C[tr]=1;
		 turnoTR_C=co;
		 while(fTR_C[co] && turnoTR_C==co);
		 // seccion critica
		 if(num>0){
 
		   if( esprimo(num)){
			//printf("numero %d ",num);
			array[cnt]=num;
			cnt++;
		   }
		   num=-1;
		 }
 
		 fTR_C[tr]=0;
		 fTR[id]=0;
 
	 }
 
	 pthread_exit(NULL);
 
}
 
void *gen(void *argg){
	int j=2;
 
	while(!fin){
 
		fTR_C[co]=1;
		turnoTR_C=tr;
		while(fTR_C[tr] && turnoTR_C==tr);
 
		if(num==-1){
			num=j;
 
		    j++;
		}
 
	    if(cnt==M){
		fin=1;
		}
        fTR_C[co]=0;
	}
	pthread_exit(NULL);
 
}
 
 
 
 
int main(){
	int i,id[2];
	pthread_t tra[2],coor;
 
	for(i=0;i<2;i++){
		id[i]=i;
	  pthread_create(&tra[i],NULL,primo,&id[i]);
 
    }
 
	pthread_create(&coor,NULL,gen,NULL);
 
	for(i=0;i<2;i++){
 
	  pthread_join(tra[i],NULL);
 
    }
 
	  pthread_join(coor,NULL);
 
	for(i=0;i<M;i++){
		printf(" %d ",array[i]);
	}
}
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar