MST

星途 面试题库

面试题:C语言Linux多线程复杂参数传递及同步

假设有一个复杂场景,在Linux下使用C语言创建多个线程,主线程需要向不同子线程传递不同类型的参数(如数组、链表等复杂数据结构),并且这些子线程之间存在数据依赖关系,需要使用同步机制(如互斥锁、条件变量)来确保数据的一致性和正确性。请详细阐述设计思路并给出完整代码示例。
15.0万 热度难度
编程语言C

知识考点

AI 面试

面试题答案

一键面试

设计思路

  1. 数据结构定义:定义用于传递给子线程的复杂数据结构,如数组和链表。
  2. 线程函数:编写每个子线程的执行函数,这些函数接收主线程传递的参数,并根据数据依赖关系进行操作。
  3. 同步机制:使用互斥锁(pthread_mutex_t)来保护共享数据,使用条件变量(pthread_cond_t)来处理线程间的依赖关系。
  4. 主线程:在主线程中创建子线程,传递相应的参数,并初始化和销毁同步机制。

代码示例

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

// 定义链表节点
typedef struct Node {
    int data;
    struct Node* next;
} Node;

// 定义传递给子线程1的参数
typedef struct {
    int arr[10];
    int arr_size;
} ArrayArgs;

// 定义传递给子线程2的参数
typedef struct {
    Node* head;
} ListArgs;

// 互斥锁
pthread_mutex_t mutex;
// 条件变量
pthread_cond_t cond;

// 子线程1函数
void* thread1_func(void* arg) {
    ArrayArgs* args = (ArrayArgs*)arg;
    pthread_mutex_lock(&mutex);
    // 处理数组数据
    for (int i = 0; i < args->arr_size; i++) {
        printf("Thread 1 processing arr[%d]: %d\n", i, args->arr[i]);
    }
    // 通知子线程2数据已准备好
    pthread_cond_signal(&cond);
    pthread_mutex_unlock(&mutex);
    pthread_exit(NULL);
}

// 子线程2函数
void* thread2_func(void* arg) {
    ListArgs* args = (ListArgs*)arg;
    pthread_mutex_lock(&mutex);
    // 等待子线程1完成
    pthread_cond_wait(&cond, &mutex);
    // 处理链表数据
    Node* current = args->head;
    while (current != NULL) {
        printf("Thread 2 processing list node: %d\n", current->data);
        current = current->next;
    }
    pthread_mutex_unlock(&mutex);
    pthread_exit(NULL);
}

int main() {
    pthread_t tid1, tid2;
    ArrayArgs arr_args;
    ListArgs list_args;

    // 初始化数组参数
    for (int i = 0; i < 10; i++) {
        arr_args.arr[i] = i;
    }
    arr_args.arr_size = 10;

    // 初始化链表参数
    Node* head = (Node*)malloc(sizeof(Node));
    head->data = 1;
    head->next = (Node*)malloc(sizeof(Node));
    head->next->data = 2;
    head->next->next = NULL;
    list_args.head = head;

    // 初始化互斥锁和条件变量
    pthread_mutex_init(&mutex, NULL);
    pthread_cond_init(&cond, NULL);

    // 创建子线程
    pthread_create(&tid1, NULL, thread1_func, &arr_args);
    pthread_create(&tid2, NULL, thread2_func, &list_args);

    // 等待子线程结束
    pthread_join(tid1, NULL);
    pthread_join(tid2, NULL);

    // 清理链表
    Node* current = list_args.head;
    Node* next;
    while (current != NULL) {
        next = current->next;
        free(current);
        current = next;
    }

    // 销毁互斥锁和条件变量
    pthread_mutex_destroy(&mutex);
    pthread_cond_destroy(&cond);

    return 0;
}

上述代码中:

  1. 定义了ArrayArgsListArgs结构体分别用于传递数组和链表给子线程。
  2. thread1_func处理数组数据,thread2_func处理链表数据,且thread2_func依赖于thread1_func完成后的数据。
  3. 使用互斥锁保护共享数据,条件变量处理线程间的依赖关系。
  4. main函数中创建子线程,传递参数,并处理同步机制的初始化和销毁。