一些pthread代码......为什么它运行缓慢?

时间:2015-02-13 22:40:11

标签: c pthreads

此代码用于协调会议中的人员。任何人都可以帮我找出它为什么这么慢?谢谢。它是用C语言编写的,并使用POSIX线程。

这是一个覆盖线程的程序,可以帮助同步一个发言者和一群健谈的记者。

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

typedef struct
{
    int ID;
}Args;

pthread_t spkr; 
pthread_t * rptr;
pthread_mutex_t mutex;

void speaker();
void * speak();
int answerStart();
int answerDone();

int reporter(int);
void * report();
void enterConferenceRoom();
void leaveConferenceRoom();
void questionStart();
void questionDone();

int repNum = 100;
int capacity = 8;
int current = 0;    

int canAsk(int);
int reporterIndex = -1;

int signal = -1;
void sendSignal(int);
int getSignal();

main(int argc, char *argv[])
{
    if(argc != 3)
        printf("Usage : <number of reporters : capacity of conference room>\n");
    else
    {
        repNum = atoi(argv[1]);
        capacity = atoi(argv[2]);   
    }

    rptr = (pthread_t *) malloc(repNum * sizeof(pthread_t));

    speaker();

    int i = 0;
    for(; i < repNum; i++)
        reporter(i);

    for(i = 0; i < repNum; i++)
        pthread_join(rptr[i], NULL);

    pthread_join(spkr, NULL);
}

void speaker()
{
    if(pthread_create( &spkr, NULL, speak, (void *) NULL ))
        { printf("\n\nSOMETHING WENT TERRIBLLY WRONG!!!\n\n"); exit(1); }
}

void * speak()
{
    while(repNum > 0)
        answerStart();

    pthread_exit(0);

    return NULL;
}

int answerStart()
{
    while(getSignal() != 1)
        if(repNum < 1)
            return;

    printf("Speaker starts to answer questions for reporter %d.\n", reporterIndex);

    answerDone();
}

int answerDone()
{
    printf("Speaker is done with answer for reporter %d.\n", reporterIndex);

    sendSignal(0);
}

int reporter(int id)
{
    Args * argum = (Args * )malloc(sizeof(Args));
    argum->ID = id;

    if(pthread_create( &rptr[id], NULL, report, (void *) argum ))
        { printf("\n\nSOMETHING WENT TERRIBLLY WRONG!!!\n\n"); exit(1); }
}

void * report(void * argum)
{
    Args * a = (Args *) argum;

    int id = a->ID;

    while(1)
        if(canEnter())
        {
            enterConferenceRoom(id);
            break;
        }

    int numQs = (id % 4 ) + 2;
    int i = 0;
    for(; i < numQs; i++)
    {
        questionStart(id);
        questionDone(id);
    }

    leaveConferenceRoom(id);

    pthread_exit(0);

    return NULL;
}

int canEnter()
{
    int ret = 0;

    pthread_mutex_lock( &mutex );

    if(current < capacity) 
    {
        current++; 
        ret = 1;
    }

    pthread_mutex_unlock( &mutex );

    return ret;
}

void enterConferenceRoom(int id)
{
    printf("Reporter %d enters the conference room.\n", id);
}

void leaveConferenceRoom(int id)
{
    printf("Reporter %d leaves the conference room.\n", id);

    pthread_mutex_lock( &mutex );

    current--;

    repNum--;

    pthread_mutex_unlock( &mutex );
}

void questionStart(int id)
{
    while(!canAsk(id));

    printf("Reporter %d asks a question.\n", id);

    sendSignal(1);
}

int canAsk(int id)
{
    int ret = 0;

    pthread_mutex_lock( &mutex );

    if(reporterIndex < 0) 
    {
        reporterIndex = id;
        ret = 1;
    }

    pthread_mutex_unlock( &mutex );

    return ret;
}

void questionDone(int id)
{
    while(getSignal() != 0);

    printf("Reporter %d is satisfied.\n", id);

    pthread_mutex_lock( &mutex );

    reporterIndex = -1;

    pthread_mutex_unlock( &mutex );
}

void sendSignal(int sig)
{
    pthread_mutex_lock( &mutex );

    signal = sig;

    pthread_mutex_unlock( &mutex );
}

int getSignal()
{
    pthread_mutex_lock( &mutex );

    int sig = signal;

    pthread_mutex_unlock( &mutex );

    return sig;
}

1 个答案:

答案 0 :(得分:3)

这是因为你有线程锁定饥饿效应。当某个线程不拥有该资源时,但在关键部分内不断检查它,从而阻止实际所有者获取锁并释放资源。

这通常发生在锁外操作时间太短的情况下。你需要在线程之间使用不同的同步,否则你会得到一个效果,因为很多人试图进入大门说话而扬声器没有机会离开这个地方......