免责声明:我是一个 C 菜鸟,正在从事一个使用共享内存段进行 IPC 的项目。我的计划是定义一个结构,它有一个指针 ( void *
) 指向映射 (via smget()
) 的剩余内存,它位于结构之外,我将使用它作为标头在进程之间传递有关请求状态的信息(它还将具有互斥体/条件结构)。
我只是想看看我这样做是否正确......我的问题在我的主要功能的评论中。
如果我不清楚某些事情,请告诉我,我对此还是很陌生。
#include <stdio.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <string.h>
#define clean_errno() (errno == 0 ? "None" : strerror(errno))
#define log_error(M, ...) fprintf(stderr, "[ERROR] (%s:%d: errno: %s) " M "\n", __FILE__, __LINE__, clean_errno(), ##__VA_ARGS__)
#define log_warn(M, ...) fprintf(stderr, "[WARN] (%s:%d: errno: %s) " M "\n", __FILE__, __LINE__, clean_errno(), ##__VA_ARGS__)
#define log_info(M, ...) fprintf(stderr, "[INFO] (%s:%d) " M "\n", __FILE__, __LINE__, ##__VA_ARGS__)
#define PATHNAME "/tmp"
typedef struct shm_data
{
/* segment id assigned by shmget() */
int segment_id;
/* max size of char *data */
unsigned int buffer_size;
/* nbytes currently in char *data to be read */
unsigned int nbytes_buffer;
/* nbytes remaining to be sent to be read */
unsigned int nbytes_remaining;
/* nbytes total that need to be read */
unsigned int nbytes_total;
/* pointer to the memory poistion just outside of the struct */
char *buffer;
} shm_data;
shm_data *create_shm(unsigned int segment_number, unsigned int segment_size)
{
int segment_id;
shm_data *shm;
// just doing segment_size + 1 for this example so when I print data it has a '\0' for output
segment_id = shmget(ftok(PATHNAME, segment_number), segment_size + 1, IPC_CREAT | S_IRUSR | S_IWUSR);
void *shm_addr = shmat(segment_id, (void *) 0, 0);
shm = (shm_data *) shm_addr;
shm->segment_id = segment_id;
shm->buffer_size = segment_size - sizeof(shm_data);
shm->nbytes_buffer = 0;
shm->nbytes_remaining = 0;
shm->nbytes_total = 0;
// 1 - am I initializing my pointer correctly? I want it to point to the first byte that comes after my struct
shm->buffer = shm_addr + sizeof(shm_data) + 1;
memset(&shm->buffer[0], '\0', shm->buffer_size);
return shm;
}
int main(int argc, char *argv[])
{
char *data = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
unsigned int segment_size = 16;
shm_data *shm = create_shm(1, sizeof(shm_data) + segment_size);
shm->nbytes_total = strlen(data);
shm->nbytes_remaining = shm->nbytes_total;
int count = 0;
while (shm->nbytes_remaining > 0)
{
// 2 - is this an appropriate way to "clear" the memory outside of the struct?
memset(&shm->buffer[0], '\0', shm->buffer_size + 1);
int nbytes = shm->nbytes_remaining;
if (nbytes > shm->buffer_size)
{
// max we can buffer is this buffer_size
nbytes = shm->buffer_size;
}
// 3 - is this an appropriate way to copy a segment of data with an offset into the memory outside of the struct?
int offset = count * shm->buffer_size;
memcpy(shm->buffer, &data[0] + offset, nbytes);
log_info("[%d] %s", nbytes, shm->buffer);
shm->nbytes_remaining = shm->nbytes_remaining - nbytes;
count++;
}
return 0;
}