线程无法正常工作 - C.

时间:2014-09-12 21:21:45

标签: c multithreading queue

我已经创建了一个队列头文件,我试图将它与线程一起使用。 我正在做的是制作2个线程,1用于从代码文件中读取字符并将字符输入队列,另一个线程正在尝试将字符打印到控制台。 问题是没有字符被打印到控制台,我无法弄清楚原因。

queue.h:

#ifndef QUEUE_INT
#define QUEUE_INT

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

typedef struct
{
    int *elementData;
    unsigned int queueSize;
    unsigned int capacityIncrement;
    unsigned int elementCount;
} Queue;

void queue_initialize(Queue*, unsigned int);
int queue_add(Queue*, int);
void queue_poll(Queue*);
int queue_peek(const Queue*);
void queue_destroy(Queue*);
bool queue_isEmpty(const Queue*);
void queue_setCapacityIncrement(Queue*, unsigned int);
unsigned int queue_getCapacityIncrement(const Queue*);
unsigned int queue_getNumberOfElements(const Queue*);
unsigned int queue_getSize(const Queue*);

void queue_initialize(Queue *p, unsigned int capacityIncrement)
{
    p->elementData = NULL;
    p->queueSize = 0;
    p->capacityIncrement = capacityIncrement;
    p->elementCount = 0;
}

int queue_add(Queue *p, int value)
{
    if(p->elementCount == p->queueSize)
    {
        int newQueueSize = p->queueSize + p->capacityIncrement;
        void *temp = realloc(p->elementData, sizeof(*p->elementData) * newQueueSize);
        if(temp == NULL || newQueueSize == 0)
        {
            return 1;
        }
        p->queueSize = newQueueSize;
        p->elementData = temp;
    }
    p->elementData[p->elementCount] = value;
    p->elementCount++;
    return 0;
}

void queue_poll(Queue *p)
{
    if(!queue_isEmpty(p))
    {
        p->elementCount--;
        if(p->queueSize - p->elementCount == p->capacityIncrement / 2 + p->capacityIncrement)
        {
            int newQueueSize = p->queueSize - p->capacityIncrement;
            p->elementData = realloc(p->elementData, sizeof(*p->elementData) * newQueueSize);
            p->queueSize = newQueueSize;
        }
        for(int i = 0; i < p->elementCount; i++)
        {
            p->elementData[i] = p->elementData[i + 1];
        }
    }
}

int queue_peek(const Queue *p)
{
    if(!queue_isEmpty(p))
    {
        return p->elementData[0];
    }
    return 0;
}

void queue_destroy(Queue *p)
{
    free(p);
}

bool queue_isEmpty(const Queue *p)
{
    return p->elementCount == 0;
}

void queue_setCapacityIncrement(Queue *p, unsigned int capacityIncrement)
{
    p->capacityIncrement = capacityIncrement;
}

unsigned int queue_getCapacityIncrement(const Queue *p)
{
    return p->capacityIncrement;
}

unsigned int queue_getNumberOfElements(const Queue *p)
{
    return p->elementCount;
}

unsigned int queue_getSize(const Queue *p)
{
    return p->queueSize;
}

#endif

代码文件:

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <process.h>
#include <time.h>
#include "queue.h"

bool isFillQueueThreadRunning;
bool isQueueProcessing;

void fillQueueThread(void*);
void popQueueThread(void*);

int main()
{
    srand(time(NULL));
    Queue q1;
    queue_initialize(&q1, 4);
    HANDLE hFillQueueThread = (HANDLE)_beginthread(fillQueueThread, 0, (void*)&q1);
    HANDLE hPopQueueThread = (HANDLE)_beginthread(fillQueueThread, 0, (void*)&q1);
    WaitForSingleObject(hFillQueueThread, 1000 * 300);
    WaitForSingleObject(hPopQueueThread, 1000 * 300);
    return 0;
}

void fillQueueThread(void *p)
{
    isFillQueueThreadRunning = true;
    Queue *q = (Queue*)p;
    FILE *f = fopen(__FILE__, "r");
    int b;
    while((b = getc(f)) != EOF)
    {
        Sleep(rand() % 50);
        while(isQueueProcessing)
        {

        }
        isQueueProcessing = true;
        if (queue_add(q, b) == 1)
        {
            break;
        }
        isQueueProcessing = false;
    }

    fclose(f);
    isFillQueueThreadRunning = false;
}

void popQueueThread(void *p)
{
    Queue *q = (Queue*)p;
    Sleep(10);
    int b;
    while(isFillQueueThreadRunning || q->elementCount > 0)
    {
        while(isQueueProcessing)
        {

        }
        isQueueProcessing = true;
        b = queue_peek(q);
        queue_poll(q);
        putchar(b);
        isQueueProcessing = false;
    }
}

2 个答案:

答案 0 :(得分:0)

_beginthread fillQueueThread两次。

你永远不会可靠地初始化isFillQueueThreadRunning。代码可能取决于未初始化的变量。

从我所见过的

答案 1 :(得分:0)

您的队列实现远非线程安全。正如Joachim所提到的,请使用线程同步原语教育自己。一个简单的互斥锁会在这里走很长的路。

请参阅:What is a mutex?

对于你的大块空间,你无条件地使用queue_peek()的输出,它可以(并且经常)为NULL。

你知道putchar(NULL)的结果是吗?