gpt4 book ai didi

c - 交替线程打印 C

转载 作者:行者123 更新时间:2023-11-30 14:54:59 25 4
gpt4 key购买 nike

我希望用线程打印一些时间(nbFois)。我做到了,但以下代码有问题。仅当所有线程获得相同的 nbFois 时间时,这才有效。

这里使用 nbAffichage[i] = 5 foreach 线程。但如果 nbAffichage 是随机的(例如,第一个是 3...第二个是 6);那么当第一个结束时,第二个就无法开始。

/* 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);
}

打印功能

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);
}

全局线程结构

typedef struct ThreadId ThreadId;
struct ThreadId
{
int indiceT[NB_THREADS_MAX];
pthread_mutex_t m[NB_THREADS_MAX];
};

ThreadId tMut;

感谢您的帮助。

编辑:整个代码

/* 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;
}

最佳答案

您对 iAffiche 的分配存在竞争条件。即使假设一切顺利,您的线程也会锁定“自己的”互斥锁 (monMut),但随后解锁其邻居的互斥锁!看起来您想要沿线传递一个 token (当线程想要循环不同次数时,这很可能会失败),但您根本不能使用这样的互斥体。

您可以尝试 semaphores 的数组反而。将它们初始化为 0,第一个线程除外,第一个线程为 1。然后,在所有线程中循环相同次数,每个线程等待其信号量,执行其工作(或者如果其 nbAffichages 值太小),然后 ups 下一个线程的信号量。您最终再次处于初始状态,信号量 vector 为 (1,0,0,...)。

关于c - 交替线程打印 C,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46361212/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com