As long as the friends who have done the project should have some understanding of the keyword static, but not understand very comprehensive. In the C language, the keyword static has the following obvious effects: The 1.static variable is assigned to static memory, which is the same as the global non-static variable.
2. In the function body, the static variable will remain unchanged in the called procedure as long as it is not modified.
3. Within the module, the global static variable can be accessed by all functions within the module, but not by other functions outside the module. It is a local global variable that has a private feature.
4. Within the module, a static function can only be called by other functions within this module. That is, this function is restricted to the local scope of the module that declares it, and also has a private feature.
If we can make good use of these characteristics of static, writing high-cohesion low-coupling, the more modular code will not appear like the slogan, if it is not well understood and use it, everything is just empty talk. Here's an example of how static may encounter problems in real-world applications.
If you are required to implement the following interface: Add header (packet header) to the audio and video bare data (Audio/video) of approximately 1600 bytes each size, and then send the entire packet that was punched in the packet to the network. Packets that have been punched in the packet format are as follows:
<------Packet----->
| header | data |
I think someone might do this:
#define MAX_PACKET_SIZE 1600
typedef struct _HEADER
{
BOOL type; /* Packet Type */
bool length; /* Packet Type */
...
}header;
BOOL send(bool Type,uint8*data,uint32 length)
{
Uint8 Packet[max_packet_size+sizeof (header)]={0};/* definition array */
header* pheader= (header*)packet;
if (Null==data | | length<1)
{
return FALSE;
}
/* Set Header */
pheader->type=type;
pheader->length=length;
pheader++;
memcpy ((uint8*) pheader,data,length);/* Copy the data to the header * *
NetSend (packet);/* Send the package to the network */
return TRUE;
}
For the above code, one might have the suspicion that sending packets to the network is a very frequent operation, so allocating stack memory frequently for packet in the send function is an inefficient practice. He may have modified the code on to:
BOOL send(bool Type,uint8*data,uint32 length)
{
uint8* packet=null;
header* Pheader=null;
if (Null==data | | length<1)
{
return FALSE;
}
packet= (uint8*) malloc (length+sizeof (header));
if (null==packet)
{
return FALSE;
}
Pheader= (header*)packet;
pheader->type=type;
pheader->length=length;
pheader++;
memcpy ((uint8*) pheader,data,length);
Net_send (packet);/* Send the package to the network */
Free (packet);
packet=null;
return TRUE;
}
Using dynamic memory seems to solve the problem above, but it does not take into account that frequent use of malloc-free can result in large amounts of memory fragmentation. In an embedded system environment, the general memory size is limited, so this practice eventually results in allocation failure. A common and efficient way to handle high-traffic data problems is to use static arrays inside functions (global static arrays are not recommended in this application because global variables increase the coupling between functions). Hey, listen to this advice, it is estimated that someone will immediately change:
BOOL send(bool Type,uint8*data,uint32 length)
{
static uint8 packet[max_packet_size+sizeof (header)]={0};
header* pheader= (header*)packet;
if (Null==data | | length<1)
{
return FALSE;
}
pheader->type=type;
pheader->length=length;
pheader++;
memcpy ((uint8*) pheader,data,length);
Net_send (packet);/* Send the package to the network */
memset (packet,0,sizeof (packet));/* Clear this memory operation */
return TRUE;
}
Wait a friend, be careful of mine!
Did you forget to consider the code reentrant (reentrance) problem? Using packet static arrays here does not have to allocate dynamic or stack memory frequently, but it also introduces the problem of non-reentrant code. Because the static variable inside the function is allocated in the memory area, it is shared by all objects. In a multitasking system, the problem is likely to occur if more than one task accesses the memory at the same time. So we have to use other means to eliminate this non-reentrant problem. Using semaphore semaphore is a good way to solve non-reentrant problems. Add the semaphore in the above code:
BOOL send(bool Type,uint8*data,uint32 length)
{
static uint8 packet[max_packet_size+sizeof (header)]={0};
header* pheader= (header*)packet;
if (Null==data | | length<1)
{
return FALSE;
}
Semtake (semaphore,wait_forever);/* Wait for the semaphore */
pheader->type=type;
pheader->length=length;
pheader++;
memcpy ((uint8*) pheader,data,length);
Net_send (packet);/* Send the package to the network */
memset (packet,0,sizeof (packet));/* Clear this memory operation */
Semgive (semaphore);/* Release the semaphore */
return TRUE;
}
OK, now it's time to solve the problem. In our video conferencing system, we've been sending data to the Web.
Stepping over the mine, modifying the bug also made a lot of effort.
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
Cleverly use static to package and send data