Ich suche, einige Male (nbFois) mit Themen zu drucken. Ich habe es gemacht, aber es gibt ein Problem mit dem folgenden Code. Dies funktioniert nur, wenn alle Threads nbFois gleich sind.Alternate Thread print C
Hier funktioniert das mit nbAffichage [i] = 5 foreach thread. Aber wenn der nbAffichage zufällig ist (zB, der erste ist 3 ... der zweite ist 6); dann, wenn das erste Ende das zweite nicht starten kann.
/* Lancer les threads afficheurs */
for (i = 0; i < nbThreads; i++) {
//nbAffichages[i] = rand() % NB_AFFICHAGES;
nbAffichages[i] = 5;
if ((etat = pthread_create(&idThdAfficheurs[i], NULL,
thd_afficher, &nbAffichages[i])) != 0)
thdErreur(etat, "Creation afficheurs", NULL);
}
Die Druckfunktion
void *thd_afficher (void *arg) {
int i, j, nbLignes;
int *nbFois = (int *)arg;
int monMut=tMut.indiceT[iAffiche];
iAffiche=(iAffiche+1)%nbThreads;
for (i = 0; i < *nbFois; i++) {
nbLignes = rand()% (*nbFois);
//nbLignes = 3;
//l'affichage est trop rapide pour voir la différence
pthread_mutex_lock (&tMut.m[monMut]);//demande accès
for (j = 0; j < nbLignes; j++) {
printf("Thread %lu, j'affiche %d-%d--------%d lignes\n", pthread_self(), i, j,nbLignes);
usleep(10);
}
pthread_mutex_unlock (&tMut.m[(monMut+1)%nbThreads]);//rend accès
}
/* Se terminer sans renvoyer de compte-rendu */
pthread_exit((void *)NULL);
}
Die globale Struktur Gewinde
typedef struct ThreadId ThreadId;
struct ThreadId
{
int indiceT[NB_THREADS_MAX];
pthread_mutex_t m[NB_THREADS_MAX];
};
ThreadId tMut;
Vielen Dank für Ihre Hilfe.
EDIT: Der gesamte Code
/* nbThread affichent un message a l'ecran
Parametre du programme : nbThread
*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#define NB_THREADS_MAX 20
//#define NB_FOIS 2
typedef struct ThreadId ThreadId;
struct ThreadId
{
int indiceT[NB_THREADS_MAX];
pthread_mutex_t m[NB_THREADS_MAX];
};
ThreadId tMut;//variable de structure avec le tableau de threads et d'indice correespondant
//Mutex ayant le droit d'écrire au début
int iAffiche=0;
int nbThreads=-1;
/*---------------------------------------------------------------------*/
/* Afficher un message d'erreur en fonction du code erreur obtenu
*/
void thdErreur(int codeErr, char *msgErr, void *codeArret) {
fprintf(stderr, "%s: %d soit %s \n", msgErr, codeErr, strerror(codeErr));
pthread_exit(codeArret);
}
/*---------------------------------------------------------------------*/
/* Fonction executee par un thread : afficher un message un certain nombre
de fois nbFois a l'ecran, nbLignes lignes de messages ou nbLignes et
genere aleatoirement
Parametre de creation du thread : nbFois, le nombre d'affichages
*/
void *thd_afficher (void *arg) {
int i, j, nbLignes;
int *nbFois = (int *)arg;
int monMut=tMut.indiceT[iAffiche];
iAffiche=(iAffiche+1)%nbThreads;
for (i = 0; i < *nbFois; i++) {
//nbLignes = rand()% (*nbFois);
nbLignes = 3;
//l'affichage est trop rapide pour voir la différence
pthread_mutex_lock (&tMut.m[monMut]);//demande accès
for (j = 0; j < nbLignes; j++) {
printf("Thread %lu, j'affiche %d-%d--------%d lignes\n", pthread_self(), i, j,nbLignes);
usleep(10);
}
pthread_mutex_unlock (&tMut.m[(monMut+1)%nbThreads]);//rend accès
}
/* Se terminer sans renvoyer de compte-rendu */
pthread_exit((void *)NULL);
}
/*---------------------------------------------------------------------*/
#define NB_AFFICHAGES 10
int main(int argc, char*argv[]) {
pthread_t idThdAfficheurs[NB_THREADS_MAX];
int i, etat;
int nbAffichages[NB_THREADS_MAX];
if (argc != 2) {
printf("Usage : %s <Nb de threads>\n", argv[0]);
exit(1);
}
nbThreads = atoi(argv[1]);
if (nbThreads > NB_THREADS_MAX)
nbThreads = NB_THREADS_MAX;
//initialisation des mutex
for (int k = 0; k < nbThreads; k++){
tMut.indiceT[k]=k;
pthread_mutex_init(&tMut.m[k],NULL);//tout les mutex init à 1
if(k!=0){
pthread_mutex_lock (&tMut.m[k]);//On retire l'accès à tous les mutex sauf le premier
}
}
/* Lancer les threads afficheurs */
for (i = 0; i < nbThreads; i++) {
//nbAffichages[i] = rand() % NB_AFFICHAGES;
nbAffichages[i] = 5;
if ((etat = pthread_create(&idThdAfficheurs[i], NULL,
thd_afficher, &nbAffichages[i])) != 0)
thdErreur(etat, "Creation afficheurs", NULL);
}
/* Attendre la fin des threads afficheur car si le thread principal
- i.e. le main() - se termine, les threads fils crees meurent aussi */
for (i = 0; i < nbThreads; i++)
if ((etat = pthread_join(idThdAfficheurs[i], NULL)) != 0)
thdErreur(etat, "Join threads afficheurs", NULL);
printf ("\nFin de l'execution du thread principal \n");
return 0;
}
Ich sehe nicht, dass "iAffiche" irgendwo definiert wird. Auch 'int monMut = tMut.indiceT [iAffiche]; iAffiche = (iAffiche + 1)% nbThreads; 'ist nicht atomar, also könnten Sie mehrere Threads mit derselben iAffiche erhalten. – PeterT
Was ist "iAffiche" und wo wird es deklariert (Speicherklasse?). Warum hat jeder Thread seinen eigenen Mutex, (sinnlos)? Warum schützen diese Mutex nur eine Druckschleife, (stdout hat sowieso eine interne Sperre)? –
Ich habe den ganzen Code am Ende hinzugefügt – Minirock