首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C,创建动态套接字线程池

C,创建动态套接字线程池
EN

Stack Overflow用户
提问于 2014-02-24 12:30:53
回答 1查看 1.6K关注 0票数 1

耶洛

我正在编写C服务器端代码,该代码旨在接受来自远程单元的连接,接收它们的数据并将它们发送到数据库中,这些单元可以同时连接,但也不能永久连接,因为它们是电池供电的。

在查看了一下之后,我选择使用一个动态线程池,这些线程可以标记为在使用中,然后在完成任务时重用它们。如果同时有更多的套接字,池本身也会增加可用线程的数量。

基本上,我已经完成了我认为可以工作的代码,但是以前没有使用过动态内存,并且知道如果您不能正确地处理它,事情会有多糟糕,我希望检查我的代码,以确保我的代码能够正常工作,并且不会在更深的一段时间内摔倒或击中我的脚。因此,对于这是一个好方法还是如果有什么问题,任何建议都会受到极大的赞赏,谢谢:)

注意,下面的代码部分仅用于动态池。我以前使用过的套接字、线程和互斥体:

代码语言:javascript
复制
#include <pthread.h>
#include <stdbool.h>
#include <stdlib.h>

#define DEFAULT_SIZE    8
#define SIZE_INCREMENTS 8

// Structure used to hold the dynamic array
typedef struct
{
    pthread_t worker;
    bool used;
} Element;

typedef struct
{
    Element *data;
    size_t size;
} DynamicPool;

// Global function prototypes
int initDynamicPool (DynamicPool *temp);
pthread_t getFreeElement (DynamicPool *temp);
int freeElement (DynamicPool *temp, pthread_t element);
int freePool (DynamicPool *temp);

// Local function prototypes
int resizePool (DynamicPool *temp);

// Create a new dynamic array
int initDynamicPool (DynamicPool *temp)
{
    if (temp->size == 0)
    {
        temp->size = DEFAULT_SIZE;
        temp->data = (Element*) malloc (temp->size * sizeof (Element));

        // Assigns defaults to new elements
        int t;
        for (t = 0; t < temp->size; t++)
        {
            //temp->data[t].worker = NULL;
            temp->data[t].used = false;
        }

        return temp->size;
    }
    else
    {
        return -1;
    }
}

// Get first free element
pthread_t getFreeElement (DynamicPool *temp)
{
    if (temp->size > 0)
    {
        // Search the array for any element that isn't used
        int t;
        for (t = 0; t < temp->size; t++)
        {
            if (!temp->data[t].used)
            {
                temp->data[t].used = true;
                return temp->data[t].worker;
            }
        }

        // If no worker found, increase the size and send the first new element
        resizePool(temp);
        temp->data[t].used = true;
        return temp->data[t].worker;
    }
    else
    {
        return -1;
    }
}

// Resize array
int resizePool (DynamicPool *temp)
{
    if (temp->size > 0)
    {
        int old_size = temp->size;
        temp->size += SIZE_INCREMENTS;
        temp->data = (Element*) realloc (temp->data, temp->size * sizeof (Element));

        // Assigns defaults to new elements
        int t;
        for (t = old_size; t < temp->size; t++)
        {
            //temp->data[t].worker = NULL;
            temp->data[t].used = false;
        }

        return temp->size;
    }
    else
    {
        return -1;
    }
}

// Free element
int freeElement (DynamicPool *temp, pthread_t element)
{
    if (temp->size > 0)
    {
        // Search the pool for the selected element
        int t;
        for (t = 0; t < temp->size; t++)
        {
            // If we find the element, null the thread and make it as unused
            if (temp->data[t].worker == element)
            {
                //temp->data[t].worker = NULL;
                temp->data[t].used = false;
                break;
            }
        }

        // If we can't find the element error out
        if (t >= temp->size)
        {
            return -2;
        }
        else
        {
            return t;
        }
    }
    else
    {
        return -1;
    }
}

// Free the pool
int freePool (DynamicPool *temp)
{
    if (temp->size > 0)
    {
        // Free the memory then reset all values incase re-initializion is intended
        free (temp->data);
        temp->size = 0;
        temp->data = NULL;

        return temp->size;
    }
    else
    {
        return -1;
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-02-24 12:58:43

您的代码是可以的,但是您必须确保所有对DynamicPool的调用都是同步的。我想您是从不同的线程调用该API的。此外,可以由多个线程修改的计数器和其他字段必须是volatile

代码语言:javascript
复制
typedef struct
{
    volatile Element *data;/* Force compiler always load/store the value */
    volatile size_t size;  /* Force compiler always load/store the value */
    pthread_mutex_t mutex; /* Protect size  and data */
} DynamicPool;

int initDynamicPool (DynamicPool *temp)
{
   ...
   pthread_mutex_init(&temp->mutex);
   ...
}

pthread_t getFreeElement (DynamicPool *temp)
{
    pthread_mutex_lock(&temp->mutex);  /* */
    ...
    pthread_mutex_unlock(&temp->mutex); /* always unlock before return */
    return res;  /* return value must be computed before unlocking */
}

等等..。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21987846

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档