Salutations !!

Pour m'amuser -- et aussi parce que j'avais besoin de lancer plusieurs threads "en même temps" (sujet d'une autre discussion... plus tard ^^) pour effectuer diverses tâches en parallèle -- j'ai commencé à écrire
quelque chose pour "synchroniser" l'exécution, ici d'un thread avec la fonction main().

A priori je pense avoir quelque chose de fonctionnel, il doit y avoir deux ou trois bugs latents et j'aurais probablement à revenir sur mon approche plusieurs fois, je fais un peu cela au "feeling".
A terme j'aimerais "trigger" un groupe de threads pour qu'ils attendent d'être lancés puis commencent leur exécution "en synchro".

Je pense avoir lu quelque part que c'était possible avec les POSIX threads, mais je n'ai pas approfondi, j'ai du temps et je trouve intéressant de programmer ce genre de trucs ^^

Mon fichier "header"
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
#ifndef SYNCEDTHREAD_H
#define SYNCEDTHREAD_H
 
// ****************************************************************************
// SECTION : fichiers d'inclusions
// ****************************************************************************
 
#include <pthread.h>
#include <semaphore.h>
 
// **************************************************************************** 
// Définitions des constantes symboliques
// **************************************************************************** 
 
// **************************************************************************** 
// Définition(s) des structures, types et énumérations
// **************************************************************************** 
 
typedef struct s_SyncedThread
{
	pthread_t	internalID;
	sem_t		*SEM_TriggerOn;
	sem_t		*SEM_Exiting;
 
	char		*pInternalName;
	bool		bRunning;
	bool		bExiting;
 
	void		(*pFunction)(void*);
 
}t_SyncedThread;
 
// **************************************************************************** 
// Définition(s) des variables statiques/externes
// **************************************************************************** 
 
extern pthread_mutex_t	MTX_Internal;
extern void							*Internal_params;
 
// **************************************************************************** 
// Définition(s) des fonctions
// **************************************************************************** 
 
 
#endif /* SYNCEDTHREAD_H */
Mon fichier source
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
// **************************************************************************** 
// Fichiers de définitions
// **************************************************************************** 

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

#include <stdbool.h>      
#include <unistd.h>
#include <string.h>

#include <pthread.h>
#include <semaphore.h>

#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>


#include "syncedthread.h"

// **************************************************************************** 
// Déclaration des constantes symboliques
// **************************************************************************** 

// **************************************************************************** 
// Déclaration des variables globales, externes, ...
// **************************************************************************** 

pthread_mutex_t MTX_Internal=PTHREAD_MUTEX_INITIALIZER;
void						*Internal_params=NULL;

// ****************************************************************************
// SECTION : prototypes des fonctions en test pour CE code source
// ****************************************************************************

t_SyncedThread* InitSyncedThread(char*,void(*)(void*));
void						RemoveThread(t_SyncedThread*);
void						PrepareThread(t_SyncedThread*,void *params);
void						RunThread(t_SyncedThread*);
void						core(void*);				

void						mabellefonction(void*);

/*
 * FONCTION PRINCIPALE
 */
int main(int argc,char** argv)
{
	t_SyncedThread *monthread=InitSyncedThread("/monbeauthread",mabellefonction);
	if(monthread==NULL) 
	{
		perror("[thread creation fatal error] ");
		return(EXIT_FAILURE);
	}
		
	int value=10;
	PrepareThread(monthread,(void*)&value);			// Comment faire pour juste passer 10 comme paramètre ???? 
	int cptTimer=5;
	while(cptTimer>=0)
	{
		sleep(1);
		printf("%03d\t",cptTimer);
		fflush(stdout);
		cptTimer--;
	}
	printf("\n");
	RunThread(monthread);
	cptTimer=5;
	while(cptTimer>=0)
	{
		sleep(1);
		printf("%03d\t",cptTimer);
		fflush(stdout);
		cptTimer--;
	}
	printf("\n");
	RemoveThread(monthread);
	return(EXIT_SUCCESS);
}

// ****************************************************************************
// SECTION : implémentation des fonctions
// ****************************************************************************

t_SyncedThread* InitSyncedThread(char *pName,void (*pFunction)(void*))
{
	t_SyncedThread *tmp=calloc(1,sizeof(t_SyncedThread));
	
	if(pName==NULL) return NULL;
	if(pFunction==NULL) tmp->pFunction=NULL;
	
	int len=strlen(pName);
	tmp->pInternalName=calloc(len,sizeof(char));
	strcpy(tmp->pInternalName,pName);
	
	tmp->SEM_TriggerOn=sem_open(tmp->pInternalName,O_CREAT,S_IRWXU);
	if(tmp->SEM_TriggerOn==NULL) return NULL;
	
	sem_init(tmp->SEM_TriggerOn,1,0);
	
	tmp->SEM_Exiting=calloc(1,sizeof(sem_t));
	sem_init(tmp->SEM_Exiting,1,0);

	tmp->internalID=-1;
	tmp->bRunning=false;
	
	tmp->pFunction=pFunction;
	
	return tmp;
}

void RemoveThread(t_SyncedThread *thisthread)
{
	if(thisthread==NULL) return;
	sem_close(thisthread->SEM_TriggerOn);
	sem_unlink(thisthread->pInternalName);
	thisthread->bRunning=false;
	thisthread->internalID=-1;
	thisthread->pFunction=NULL;
	free(thisthread->pInternalName);
	free(thisthread->SEM_Exiting);
	thisthread->pInternalName=NULL;
}

void PrepareThread(t_SyncedThread *thisthread,void *params)
{
	Internal_params=params;
	pthread_create(&thisthread->internalID,NULL,(void*)core,(void*)thisthread);
}

void	RunThread(t_SyncedThread *thisThread)
{
	if(thisThread->SEM_TriggerOn==NULL) return;
	sem_post(thisThread->SEM_TriggerOn);
}

void	StopThread(t_SyncedThread *thisthread)
{
	if(thisthread->SEM_Exiting==NULL) return;
	sem_post(thisthread->SEM_Exiting);
}

void core(void *wrapped)
{
	t_SyncedThread *thisthread=(t_SyncedThread*)wrapped;
	
	if(thisthread->pFunction==NULL) return;
	sem_wait(thisthread->SEM_TriggerOn);
	thisthread->bRunning=true;
	pthread_mutex_lock(&MTX_Internal);
	thisthread->pFunction((void*)Internal_params);
	pthread_mutex_unlock(&MTX_Internal);
	thisthread->bExiting=true;
	sem_wait(thisthread->SEM_Exiting);
	thisthread->bExiting=false;
	thisthread->bRunning=false;
}

void mabellefonction(void *params)
{
	int *pMax=calloc(1,sizeof(int));
	memcpy(pMax,params,sizeof(int));
	while(*pMax>=0)
	{
		printf("coucou !!\n");
		(*pMax)--;
	}
}
Mon programme fonctionne, avec un seul thread... tout va bien.
Cependant... je voudrais pouvoir passer des valeurs comme paramètres sans devoir passer par une variable... (si je mets (void*)10 l'adresse de Internal_params sera 0xa du coup et je serais dans le vecteur d'interruptions ou une saloperie du genre :{ )
...je me demande si cela est possible avec les pointeurs génériques de (type void*)

J'ai une connaissance assez bonne des pointeurs mais là je suis un peu dubitatif... je ne pense pas que ce soit possible d'utiliser un littéral casté en (void*)... c'est obligatoirement une adresse qui se trouve à droite de la parenthèse fermante...

Nom : firsttry000.png
Affichages : 161
Taille : 8,8 Ko