c多线程教程linux
- 行业动态
- 2025-02-06
- 4649
在Linux环境下进行C语言多线程编程,需要掌握一些基本概念和关键函数,以下是关于C语言多线程编程的详细教程:
一、基础概念
1、线程:线程是进程中的一个执行单元,它独立运行并共享进程的资源,线程的引入使得一个程序可以同时执行多个任务,从而提高了程序的执行效率和响应速度。
2、POSIX线程库(Pthreads):这是一个标准的线程库,提供了创建和管理线程的函数,它是大多数Unix/Linux系统默认支持的多线程编程接口。
二、创建线程
1、pthread_create函数:使用Pthreads库创建线程的基本函数是pthread_create,该函数的原型如下:
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);
thread
:指向pthread_t类型的指针,用于存储新线程的标识符。
attr
:指向pthread_attr_t类型的指针,用于设置线程属性,通常传递NULL。
start_routine
:新线程将要执行的函数,该函数必须返回void并接受一个void类型的参数。
arg
:传递给start_routine函数的参数。
2、示例代码:以下是一个创建并启动多个线程的简单示例:
#include <pthread.h> #include <stdio.h> #include <stdlib.h> #define NUM_THREADS 5 void* print_hello(void* threadid) { long tid; tid = (long)threadid; printf("Hello World! It's me, thread #%ld!n", tid); pthread_exit(NULL); } int main(int argc, char* argv[]) { pthread_t threads[NUM_THREADS]; int rc; long t; for (t = 0; t < NUM_THREADS; t++) { printf("In main: creating thread %ldn", t); rc = pthread_create(&threads[t], NULL, print_hello, (void*)t); if (rc) { printf("ERROR; return code from pthread_create() is %dn", rc); exit(-1); } } pthread_exit(NULL); }
在这个示例中,我们创建了5个线程,每个线程都会执行print_hello函数,并输出其线程ID。
三、线程同步
1、互斥锁(Mutex):互斥锁用于保护共享资源,防止多个线程同时访问造成数据不一致,使用Pthreads库中的互斥锁需要以下步骤:
初始化互斥锁:pthread_mutex_init
加锁:pthread_mutex_lock
解锁:pthread_mutex_unlock
销毁互斥锁:pthread_mutex_destroy
2、示例代码:以下是一个使用互斥锁保护共享资源的示例:
#include <pthread.h> #include <stdio.h> #include <stdlib.h> #define NUM_THREADS 5 pthread_mutex_t lock; int counter = 0; void* increment_counter(void* threadid) { long tid; tid = (long)threadid; pthread_mutex_lock(&lock); counter++; printf("Thread #%ld incremented counter to %dn", tid, counter); pthread_mutex_unlock(&lock); pthread_exit(NULL); } int main(int argc, char* argv[]) { pthread_t threads[NUM_THREADS]; int rc; long t; pthread_mutex_init(&lock, NULL); for (t = 0; t < NUM_THREADS; t++) { printf("In main: creating thread %ldn", t); rc = pthread_create(&threads[t], NULL, increment_counter, (void*)t); if (rc) { printf("ERROR; return code from pthread_create() is %dn", rc); exit(-1); } } for (t = 0; t < NUM_THREADS; t++) { pthread_join(threads[t], NULL); } pthread_mutex_destroy(&lock); pthread_exit(NULL); }
在这个示例中,每个线程都会加锁、增加counter变量并解锁,确保了对共享资源的安全访问。
四、条件变量
1、条件变量的概念:条件变量用于使线程能够等待另一个线程满足某个条件,它通常与互斥锁一起使用,以确保在检查和等待条件时,条件变量受到保护。
2、使用条件变量的步骤:
初始化条件变量:pthread_cond_init
等待条件:pthread_cond_wait
发信号通知条件满足:pthread_cond_signal
或pthread_cond_broadcast
销毁条件变量:pthread_cond_destroy
3、示例代码:以下是一个使用条件变量的示例:
#include <pthread.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t cond = PTHREAD_COND_INITIALIZER; int ready = 0; void* thread1(void* arg) { pthread_mutex_lock(&mutex); while (!ready) { printf("Thread 1: waiting for the condition to be true...n"); pthread_cond_wait(&cond, &mutex); } printf("Thread 1: the condition is now true, proceeding...n"); pthread_mutex_unlock(&mutex); return NULL; } void* thread2(void* arg) { sleep(1); // Ensure that thread1 gets to run first and waits on the condition pthread_mutex_lock(&mutex); ready = 1; printf("Thread 2: setting the condition to true and signaling thread 1...n"); pthread_cond_signal(&cond); pthread_mutex_unlock(&mutex); return NULL; } int main() { pthread_t t1, t2; pthread_create(&t1, NULL, thread1, NULL); pthread_create(&t2, NULL, thread2, NULL); pthread_join(t1, NULL); pthread_join(t2, NULL); return 0; }
在这个示例中,线程1会等待条件变量变为真,而线程2会设置条件变量为真并通知线程1。
五、FAQs
1、Q: 为什么需要使用互斥锁?
A: 互斥锁用于保护共享资源,防止多个线程同时访问造成数据不一致,当多个线程尝试访问同一个共享资源时,互斥锁可以确保同一时刻只有一个线程能够访问该资源。
2、Q: 条件变量和互斥锁有什么区别?
A: 条件变量通常与互斥锁一起使用,用于使线程能够等待另一个线程满足某个条件,互斥锁主要用于保护共享资源,而条件变量则用于控制线程的执行顺序和协调线程之间的工作。
六、小编有话说
多线程编程虽然可以提高程序的执行效率和响应速度,但也增加了程序的复杂性和调试难度,在进行多线程编程时,需要仔细设计程序的逻辑和同步机制,确保程序的正确性和稳定性。