交替螺纹打印C
我正在寻找打印一些时间(NBFOI)与线程。我这样做了,但是下面的代码有一个问题。只有当所有线程获得相同的nbFois时间时,这才有效 这里使用的是nbAffichage[i]=5 foreach线程。 但是如果nbAffichage是随机的(例如,第一个是3…第二个是6);当第一个结束时,第二个就不能开始了交替螺纹打印C,c,mutex,C,Mutex,我正在寻找打印一些时间(NBFOI)与线程。我这样做了,但是下面的代码有一个问题。只有当所有线程获得相同的nbFois时间时,这才有效 这里使用的是nbAffichage[i]=5 foreach线程。 但是如果nbAffichage是随机的(例如,第一个是3…第二个是6);当第一个结束时,第二个就不能开始了 /* Lancer les threads afficheurs */ for (i = 0; i < nbThreads; i++) { //nbAffichages[
/* 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);
}
谢谢你的帮助
编辑:整个代码
/* 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;
}
/*nbThread将联合国信息附加到一个l'ecran上
程序参数:nbThread
*/
#包括
#包括
#包括
#包括
#包括
#定义NB_螺纹最多20个
//#定义NB_FOIS 2
typedef struct ThreadId ThreadId;
结构线程ID
{
int指示器[NB_螺纹_最大值];
pthread_mutex_t m[NB_THREADS_MAX];
};
ThreadId-tMut//相应螺纹和标记的可变结构表
//但是,这是一个很好的选择
int iAffiche=0;
int-nbThreads=-1;
/*---------------------------------------------------------------------*/
/*将错误信息粘贴到代码错误列表中
*/
void-thdErreur(int-codeErr,char*msgErr,void*codeArret){
fprintf(标准字符,“%s:%d soit%s\n”、msgErr、codeErr、strerror(codeErr));
pthread_exit(coderarret);
}
/*---------------------------------------------------------------------*/
联合执行线程:连接未指定的消息
这是一张便笺,上面写着你的信息
通用航空公司
线程创建参数:nbFois,le nombre d'affichages
*/
void*thd\u附件(void*arg){
int i,j,NBALIGNES;
int*nbFois=(int*)arg;
int monMut=tMut.indiciet[iAffiche];
iAffiche=(iAffiche+1)%n线程;
对于(i=0;i<*nbFois;i++){
//nbLignes=rand()%(*nbFois);
nbLignes=3;
//这是一个有差别的急流
pthread_mutex_lock(&tMut.m[monMut]);//demande accès
对于(j=0;jNB螺纹最大值)
NB螺纹=NB螺纹\u最大值;
//互斥体初始化
对于(int k=0;k
您在分配给iAffiche
的任务上有一个竞赛条件。即使假设一切顺利,线程也会锁定“自己的”互斥锁(monMut
),但会解锁邻居的互斥锁!看起来您想要传递一个令牌(当线程想要循环不同的次数时,很可能会失败),但是您根本不能使用这样的互斥体
您可以尝试使用的数组。将它们初始化为0,但第一个线程除外,该线程为1。然后,在所有线程之间循环相同次数,每个线程等待其信号量,执行其工作(如果其
nbAffichages
值太小,则不执行任何操作),然后向上更新下一个线程的信号量。您最终再次处于初始状态,信号量向量为(1,0,0,…)我看不到任何地方定义了iAffiche
。也int monMut=tMut.indicate[iAffiche];iAffiche=(iAffiche+1)%n线程代码>不是原子的,因此您可能会得到多个具有相同iAffiche的线程。“iAffiche”是什么,它在哪里声明,(存储类?)。为什么每个线程都有自己的互斥锁(毫无意义)?为什么那些互斥锁只保护一个打印循环(stdout有一个内部锁)?我在末尾添加了all代码,正如Davis在回答时所说,你使用互斥锁是为了一个完全不合适的目的。尝试使用信号量,来回传递“立即运行”令牌/单元。我想打印线程1的第一条消息…然后打印线程2的第一条消息。然后是线程1的第二条消息…然后是线程2的第二条消息。-->如果两个线程的nbAffichage=2,这很好……但是如果第二个线程的nbAffichage=4,这就不起作用了。我明白为什么了……但我不知道如何解决它。我认为您的测试给您一个错误的印象,即nbAffichage
中的变化是主要问题。最简单的(如果不是非常有效的)解决方案是一个障碍,即所有线程连接N次,即使它们只打印Ntypedef 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;
}