问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

C语言中创建线程的多种方法详解

创作时间:
作者:
@小白创作中心

C语言中创建线程的多种方法详解

引用
1
来源
1.
https://docs.pingcode.com/baike/989886

在C语言中创建线程是实现多线程编程的基础,它能够显著提升程序的执行效率和响应速度。本文将详细介绍如何使用POSIX线程库、WinAPI线程函数和GCC内置函数等方法在C语言中创建和管理线程,并通过丰富的示例代码帮助读者快速掌握这些技术。

在C语言中创建线程的方法有多种,最常见的方式是使用POSIX线程库(pthread)、WinAPI线程函数、GCC内置函数。本文将详细介绍如何使用这些方法在C语言中创建和管理线程。

一、POSIX线程库(pthread)

POSIX线程库是UNIX标准的一部分,广泛应用于Linux和其他类UNIX系统。它提供了丰富的线程操作函数,包括创建、管理和终止线程。

1. 基本概念

POSIX线程库(pthread)提供了一组标准化的API,允许程序员在C语言中创建和控制线程。线程是一种轻量级的进程,可以并发执行多个任务,从而提高程序的效率。

2. 创建线程

使用pthread库创建线程的基本步骤如下:

  1. 包含头文件 <pthread.h>
  2. 定义一个线程函数,该函数将在线程中运行
  3. 使用 pthread_create 函数创建线程

以下是一个简单的示例程序:

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

// 线程函数
void* myThreadFunction(void* arg) {
    int* num = (int*)arg;
    printf("线程 %d 正在运行\n", *num);
    pthread_exit(NULL);
}

int main() {
    pthread_t thread;
    int threadArg = 1;

    // 创建线程
    if (pthread_create(&thread, NULL, myThreadFunction, (void*)&threadArg)) {
        fprintf(stderr, "Error creating thread\n");
        return 1;
    }

    // 等待线程完成
    if (pthread_join(thread, NULL)) {
        fprintf(stderr, "Error joining thread\n");
        return 2;
    }

    printf("主线程完成\n");
    return 0;
}

在这个示例中,我们首先包含了 pthread.h 头文件,然后定义了一个名为 myThreadFunction 的线程函数。接下来,我们在主函数中使用 pthread_create 函数创建一个新线程,并将 myThreadFunction 传递给该线程。最后,我们使用 pthread_join 函数等待线程完成。

3. 线程同步

在多线程编程中,线程同步是一个重要的概念。POSIX线程库提供了多种同步机制,例如互斥锁(mutex)和条件变量(condition variable)。

互斥锁

互斥锁用于保护共享资源,确保同一时刻只有一个线程访问该资源。以下是一个使用互斥锁的示例:

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

pthread_mutex_t lock;

void* myThreadFunction(void* arg) {
    pthread_mutex_lock(&lock);
    printf("线程 %d 正在运行\n", *(int*)arg);
    pthread_mutex_unlock(&lock);
    pthread_exit(NULL);
}

int main() {
    pthread_t threads[2];
    int threadArgs[2] = {1, 2};

    pthread_mutex_init(&lock, NULL);

    for (int i = 0; i < 2; i++) {
        if (pthread_create(&threads[i], NULL, myThreadFunction, (void*)&threadArgs[i])) {
            fprintf(stderr, "Error creating thread\n");
            return 1;
        }
    }

    for (int i = 0; i < 2; i++) {
        if (pthread_join(threads[i], NULL)) {
            fprintf(stderr, "Error joining thread\n");
            return 2;
        }
    }

    pthread_mutex_destroy(&lock);
    printf("主线程完成\n");
    return 0;
}

在这个示例中,我们使用 pthread_mutex_lockpthread_mutex_unlock 函数保护共享资源。线程在访问共享资源时首先获取互斥锁,完成操作后释放锁。

二、WinAPI线程函数

在Windows系统中,可以使用WinAPI提供的线程函数来创建和管理线程。

1. 创建线程

使用WinAPI创建线程的基本步骤如下:

  1. 包含头文件 <windows.h>
  2. 定义一个线程函数
  3. 使用 CreateThread 函数创建线程

以下是一个简单的示例程序:

#include <stdio.h>
#include <windows.h>

// 线程函数
DWORD WINAPI myThreadFunction(LPVOID arg) {
    int* num = (int*)arg;
    printf("线程 %d 正在运行\n", *num);
    return 0;
}

int main() {
    HANDLE thread;
    DWORD threadId;
    int threadArg = 1;

    // 创建线程
    thread = CreateThread(
        NULL,        // 默认安全属性
        0,           // 默认堆栈大小
        myThreadFunction, // 线程函数
        &threadArg,  // 线程参数
        0,           // 默认创建标志
        &threadId    // 接收线程ID
    );

    if (thread == NULL) {
        fprintf(stderr, "Error creating thread\n");
        return 1;
    }

    // 等待线程完成
    WaitForSingleObject(thread, INFINITE);
    printf("主线程完成\n");
    return 0;
}

在这个示例中,我们首先包含了 windows.h 头文件,然后定义了一个名为 myThreadFunction 的线程函数。接下来,我们在主函数中使用 CreateThread 函数创建一个新线程,并将 myThreadFunction 传递给该线程。最后,我们使用 WaitForSingleObject 函数等待线程完成。

2. 线程同步

在Windows系统中,可以使用互斥锁(Mutex)、信号量(Semaphore)和事件(Event)等同步机制。

互斥锁

以下是一个使用互斥锁的示例:

#include <stdio.h>
#include <windows.h>

HANDLE mutex;

DWORD WINAPI myThreadFunction(LPVOID arg) {
    WaitForSingleObject(mutex, INFINITE);
    printf("线程 %d 正在运行\n", *(int*)arg);
    ReleaseMutex(mutex);
    return 0;
}

int main() {
    HANDLE threads[2];
    DWORD threadIds[2];
    int threadArgs[2] = {1, 2};

    mutex = CreateMutex(NULL, FALSE, NULL);

    for (int i = 0; i < 2; i++) {
        threads[i] = CreateThread(
            NULL, 0, myThreadFunction, &threadArgs[i], 0, &threadIds[i]
        );
    }

    WaitForMultipleObjects(2, threads, TRUE, INFINITE);
    CloseHandle(mutex);
    printf("主线程完成\n");
    return 0;
}

在这个示例中,我们使用 WaitForSingleObject 函数获取互斥锁,完成操作后使用 ReleaseMutex 函数释放锁。

三、GCC内置函数

GCC提供了一些内置函数,可以用于创建和管理线程。

1. 创建线程

使用GCC内置函数创建线程的基本步骤如下:

  1. 包含头文件 <stdatomic.h>
  2. 定义一个线程函数
  3. 使用 __builtin_thread_create 函数创建线程

以下是一个简单的示例程序:

#include <stdio.h>
#include <stdatomic.h>

void* myThreadFunction(void* arg) {
    int* num = (int*)arg;
    printf("线程 %d 正在运行\n", *num);
    return NULL;
}

int main() {
    atomic_thread_t thread;
    int threadArg = 1;

    __builtin_thread_create(&thread, myThreadFunction, &threadArg);
    __builtin_thread_join(thread);
    printf("主线程完成\n");
    return 0;
}

在这个示例中,我们首先包含了 stdatomic.h 头文件,然后定义了一个名为 myThreadFunction 的线程函数。接下来,我们在主函数中使用 __builtin_thread_create 函数创建一个新线程,并将 myThreadFunction 传递给该线程。最后,我们使用 __builtin_thread_join 函数等待线程完成。

四、线程池

线程池是一种优化多线程程序性能的技术,通过预先创建一组线程来处理任务,避免频繁创建和销毁线程的开销。

1. 实现线程池

以下是一个简单的线程池实现示例:

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

#define THREAD_POOL_SIZE 4

typedef struct {
    void (*function)(void*);
    void* arg;
} thread_task_t;

pthread_mutex_t lock;
pthread_cond_t cond;
thread_task_t tasks[THREAD_POOL_SIZE];
int task_count = 0;

void* thread_function(void* arg) {
    while (1) {
        pthread_mutex_lock(&lock);
        while (task_count == 0) {
            pthread_cond_wait(&cond, &lock);
        }
        thread_task_t task = tasks[--task_count];
        pthread_mutex_unlock(&lock);
        task.function(task.arg);
    }
    return NULL;
}

void thread_pool_init(pthread_t* threads) {
    pthread_mutex_init(&lock, NULL);
    pthread_cond_init(&cond, NULL);
    for (int i = 0; i < THREAD_POOL_SIZE; i++) {
        pthread_create(&threads[i], NULL, thread_function, NULL);
    }
}

void thread_pool_add_task(void (*function)(void*), void* arg) {
    pthread_mutex_lock(&lock);
    tasks[task_count++] = (thread_task_t){function, arg};
    pthread_cond_signal(&cond);
    pthread_mutex_unlock(&lock);
}

int main() {
    pthread_t threads[THREAD_POOL_SIZE];
    thread_pool_init(threads);

    void task_function(void* arg) {
        int* num = (int*)arg;
        printf("任务 %d 正在运行\n", *num);
    }

    int task_args[4] = {1, 2, 3, 4};

    for (int i = 0; i < 4; i++) {
        thread_pool_add_task(task_function, &task_args[i]);
    }

    for (int i = 0; i < THREAD_POOL_SIZE; i++) {
        pthread_join(threads[i], NULL);
    }

    pthread_mutex_destroy(&lock);
    pthread_cond_destroy(&cond);
    printf("主线程完成\n");
    return 0;
}

在这个示例中,我们创建了一个简单的线程池,预先创建了4个线程来处理任务。线程池使用互斥锁和条件变量来同步任务的添加和执行。

总结

在C语言中创建线程的方法有多种,最常见的方式是使用POSIX线程库(pthread)、WinAPI线程函数、GCC内置函数。本文详细介绍了如何使用这些方法在C语言中创建和管理线程,并提供了丰富的示例代码。此外,还介绍了线程同步和线程池的实现方法。通过掌握这些技术,开发者可以编写高效、并发的C语言程序。

在实际项目中,选择适合的线程创建和管理方法,以及合理的同步机制,是确保程序稳定和高效运行的关键。如果需要更加专业的项目管理系统,可以考虑使用研发项目管理系统PingCode和通用项目管理软件Worktile,它们提供了强大的功能,帮助团队更好地管理和协作。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号