当前位置:首页 > 行业动态 > 正文

c多线程编程实例linux

本文通过四个实例详细介绍了Linux环境下C语言的多线程编程,包括线程的创建、退出、属性设置,以及互斥锁和信号量的使用。这些示例展示了如何在多线程中管理共享资源,确保并发访问的安全性。

在Linux系统中,C语言多线程编程是一项强大的技术,它允许程序同时执行多个任务,从而充分利用系统资源,提高程序的并发性能和响应速度,以下是关于C多线程编程实例的详细内容:

一、基础概念

1、线程:线程是进程中的一个实体,是CPU调度和分派的基本单位,它是比进程更小的独立运行的单位,一个进程可以拥有多个线程,这些线程共享进程的地址空间和资源。

2、pthread库:在Linux中,进行多线程编程通常使用pthread库,pthread库提供了丰富的函数来创建、管理和同步线程。pthread_create用于创建新线程,pthread_join用于等待指定线程结束,pthread_mutex_lockpthread_mutex_unlock用于互斥锁的操作等。

二、简单实例

以下是一个使用pthread库创建两个线程的简单示例,每个线程输出一段信息:

c多线程编程实例linux

#include <pthread.h>
#include <stdio.h>
// 线程函数
void *print_message(void *ptr) {
    char *message;
    message = (char *) ptr;
    printf("%s 
", message);
    return NULL;
}
int main() {
    pthread_t thread1, thread2;
    const char *message1 = "Thread 1";
    const char *message2 = "Thread 2";
    int ret;
    // 创建线程1
    ret = pthread_create(&thread1, NULL, print_message, (void*) message1);
    if (ret) {
        fprintf(stderr, "Error: pthread_create() failed for thread 1
");
        return 1;
    }
    // 创建线程2
    ret = pthread_create(&thread2, NULL, print_message, (void*) message2);
    if (ret) {
        fprintf(stderr, "Error: pthread_create() failed for thread 2
");
        return 1;
    }
    // 等待线程结束
    pthread_join(thread1, NULL);
    pthread_join(thread2, NULL);
    return 0;
}

这个程序首先定义了一个线程函数print_message,该函数接收一个指针参数并输出对应的消息,在main函数中,创建了两个线程thread1thread2,分别将不同的消息传递给它们,然后使用pthread_join等待两个线程结束。

三、传递参数实例

下面是一个向线程传递参数的示例,每个线程打印一个整数:

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
// 线程函数
void *print_number(void *ptr) {
    int num;
    num = *((int*) ptr);
    printf("Number: %d
", num);
    return NULL;
}
int main() {
    pthread_t thread1, thread2;
    int num1 = 1, num2 = 2;
    int ret;
    // 创建线程1并传递参数
    ret = pthread_create(&thread1, NULL, print_number, &num1);
    if (ret) {
        fprintf(stderr, "Error: pthread_create() failed for thread 1
");
        return 1;
    }
    // 创建线程2并传递参数
    ret = pthread_create(&thread2, NULL, print_number, &num2);
    if (ret) {
        fprintf(stderr, "Error: pthread_create() failed for thread 2
");
        return 1;
    }
    // 等待线程结束
    pthread_join(thread1, NULL);
    pthread_join(thread2, NULL);
    return 0;
}

在这个示例中,定义了一个整型变量num1num2,并将它们的地址作为参数传递给线程函数print_number,线程函数中通过强制类型转换获取整数值并打印。

c多线程编程实例linux

四、线程同步实例——互斥锁

当多个线程需要访问共享资源时,为了避免竞态条件,需要使用同步机制,下面是一个使用互斥锁实现线程同步的示例,多个线程对同一个全局变量进行递增操作:

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#define NUM_THREADS 5
int counter = 0;
pthread_mutex_t mutex;
// 线程函数
void *increment_counter(void *arg) {
    for (int i = 0; i < 10000; i++) {
        pthread_mutex_lock(&mutex); // 加锁
        counter++;
        pthread_mutex_unlock(&mutex); // 解锁
    }
    return NULL;
}
int main() {
    pthread_t threads[NUM_THREADS];
    int ret;
    // 初始化互斥锁
    pthread_mutex_init(&mutex, NULL);
    // 创建线程
    for (int i = 0; i < NUM_THREADS; i++) {
        ret = pthread_create(&threads[i], NULL, increment_counter, NULL);
        if (ret) {
            fprintf(stderr, "Error: pthread_create() failed for thread %d
", i);
            return 1;
        }
    }
    // 等待线程结束
    for (int i = 0; i < NUM_THREADS; i++) {
        pthread_join(threads[i], NULL);
    }
    // 销毁互斥锁
    pthread_mutex_destroy(&mutex);
    // 打印最终的计数值
    printf("Final counter value: %d
", counter);
    return 0;
}

在这个示例中,定义了一个全局变量counter和一个互斥锁mutex,在increment_counter线程函数中,每次对counter进行递增操作前先加锁,操作完成后解锁,这样可以确保同一时刻只有一个线程能够修改counter的值,避免了竞态条件的发生,主函数中创建了多个线程,并在所有线程结束后打印最终的计数值。

五、FAQs

1、Q:什么是线程安全?

A:线程安全是指当多个线程同时访问某个资源或执行某段代码时,能够保证程序的正确性和数据的一致性,实现线程安全通常需要使用同步机制,如互斥锁、条件变量等,以避免竞态条件和数据竞争等问题,在上述的互斥锁示例中,通过对共享变量counter的访问加锁,保证了多个线程同时递增counter时不会出现错误的结果。

c多线程编程实例linux

2、Q:如何避免死锁?

A:死锁是指两个或多个线程在执行过程中,因争夺资源而造成的一种互相等待的现象,如果没有外力作用,它们都将无法推进下去,为了避免死锁,可以采取以下措施:一是避免一个线程同时获取多个资源,尽量按照固定的顺序获取资源;二是使用超时机制,当一个线程尝试获取资源超过一定时间后,放弃获取并释放已占有的资源;三是使用死锁检测算法,定期检查系统中是否存在死锁情况,并采取措施解除死锁,在编写多线程程序时,需要仔细设计资源的分配和释放逻辑,避免出现死锁的可能性。