MST

星途 面试题库

面试题:C语言匿名联合体在复杂系统设计中的优化应用

在一个嵌入式系统中,需要频繁处理多种不同格式的传感器数据,这些数据格式之间存在一些可复用的内存区域,使用匿名联合体可以优化内存和处理效率。请设计一个基于匿名联合体的数据处理框架,包括数据的接收、解析、存储和转发功能,要考虑系统的可扩展性、兼容性以及多线程环境下的并发访问问题。
50.3万 热度难度
编程语言C

知识考点

AI 面试

面试题答案

一键面试

1. 定义匿名联合体

// 假设传感器数据格式
typedef struct {
    uint16_t sensorId;
    uint32_t timestamp;
    // 其他通用字段
} SensorDataCommon;

typedef struct {
    float value1;
    // 特定于格式1的其他字段
} SensorDataFormat1;

typedef struct {
    int32_t value2;
    // 特定于格式2的其他字段
} SensorDataFormat2;

union {
    SensorDataCommon common;
    SensorDataFormat1 format1;
    SensorDataFormat2 format2;
} __attribute__((packed)) SensorDataUnion;

2. 数据接收

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

#define BUFFER_SIZE 1024
SensorDataUnion dataBuffer[BUFFER_SIZE];
int bufferIndex = 0;

// 模拟数据接收函数
void receiveData(uint8_t *rawData, size_t length) {
    // 这里需要根据实际的协议解析rawData
    // 假设已经解析出正确的数据格式并填充到union中
    SensorDataUnion newData;
    // 解析数据到newData中
    if (bufferIndex < BUFFER_SIZE) {
        dataBuffer[bufferIndex++] = newData;
    }
}

3. 数据解析

// 解析函数
void parseData(SensorDataUnion *data) {
    switch (data->common.sensorId) {
        case 1:
            // 处理格式1的数据
            printf("Format1: value1 = %f\n", data->format1.value1);
            break;
        case 2:
            // 处理格式2的数据
            printf("Format2: value2 = %d\n", data->format2.value2);
            break;
        default:
            break;
    }
}

4. 数据存储

// 简单的存储函数,这里可以替换为实际的存储实现,如文件存储或数据库存储
void storeData(SensorDataUnion *data) {
    // 示例:打印存储信息
    printf("Storing data with sensorId: %d\n", data->common.sensorId);
}

5. 数据转发

// 转发函数,假设通过网络转发,这里只做简单模拟
void forwardData(SensorDataUnion *data) {
    // 示例:打印转发信息
    printf("Forwarding data with sensorId: %d\n", data->common.sensorId);
}

6. 多线程处理

pthread_mutex_t bufferMutex = PTHREAD_MUTEX_INITIALIZER;

// 线程函数,用于处理数据
void* processDataThread(void* arg) {
    while (1) {
        SensorDataUnion data;
        pthread_mutex_lock(&bufferMutex);
        if (bufferIndex > 0) {
            data = dataBuffer[--bufferIndex];
        }
        pthread_mutex_unlock(&bufferMutex);
        if (bufferIndex >= 0) {
            parseData(&data);
            storeData(&data);
            forwardData(&data);
        }
    }
    return NULL;
}

7. 主函数及框架整合

int main() {
    pthread_t thread;
    pthread_create(&thread, NULL, processDataThread, NULL);

    // 模拟数据接收
    uint8_t rawData[10];
    // 填充rawData
    receiveData(rawData, sizeof(rawData));

    pthread_join(thread, NULL);
    pthread_mutex_destroy(&bufferMutex);
    return 0;
}

8. 可扩展性与兼容性

  • 可扩展性:通过在switch语句中增加新的case分支来处理新的数据格式,在联合体中添加新的结构体来支持新的数据格式。同时,存储和转发函数可以根据新需求进行扩展。
  • 兼容性:匿名联合体的设计保证了不同数据格式间复用内存区域,使得不同格式的数据可以以统一的方式进行处理。对于新的数据格式,只要保证SensorDataCommon结构不变,并且新结构体与现有结构体布局不冲突,就可以兼容。

通过上述设计,我们实现了一个基于匿名联合体的数据处理框架,具备数据接收、解析、存储和转发功能,并考虑了多线程并发访问、可扩展性以及兼容性。