黄釉,
我正在编写C服务器端代码,旨在接受来自远程单元的连接,从它们接收数据并将它们发布到数据库中,这些单元可以同时连接但也不能永久连接,因为它们是电池供电。
在看过之后,我选择使用可以标记为正在使用的动态pthread池,然后在单元完成后重新使用。如果同时有更多的套接字,池本身也会增加可用线程的数量。
基本上我已经完成了我认为可行的代码,但之前没有使用过动态内存,并且知道如果你没有正确处理它会有多么糟糕的事情,我希望我的代码检查完毕确保我所拥有的将会发挥作用,并且不会摔倒或射击我的脚。因此,如果这是一个好的方法或者有什么问题的任何建议将非常感谢,谢谢:),
请注意,下面的代码部分仅适用于动态池。我之前使用的套接字,线程和互斥锁:
#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;
}
}
答案 0 :(得分:1)
您的代码没问题,但您必须确保所有对DynamicPool
的调用都已同步。我假设您从不同的线程调用该API。此外,可由多个线程修改的计数器和其他字段必须为volatile
。
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 */
}
等等......