1. 前言
本文主要讲解在linux系统下使用C语言编写多线程程序的入门指南。多线程程序指能够同时执行多个线程的程序,这在并发编程中十分有用。本文将从多线程的概念、线程创建、线程同步、线程销毁等方面介绍多线程的相关概念和操作。
2. 多线程概念
2.1 什么是线程?
线程是独立执行的基本单元,是进程中的一个实体。一个进程可以包含多个线程,它们共享进程的内存空间和资源。
多线程的优点:
提高程序的并发性和效率
增加程序的响应速度
提高程序的适应性和稳定性
2.2 线程的生命周期
线程的生命周期包括:
线程创建
线程就绪
线程运行
线程阻塞
线程销毁
3. 线程创建
在C语言中,可以使用pthread库来创建和管理线程。其中,pthread_create函数用于创建一个新的线程,函数原型如下:
#include <pthread.h>
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg);
thread:返回新线程的ID
attr:线程属性对象
start_routine:线程函数的指针
arg:线程函数的参数
下面是一个使用pthread_create函数创建线程的例子:
#include <stdio.h>
#include <pthread.h>
void *thread_func(void *arg)
{
int i;
for (i = 0; i < 10; i++) {
printf("This is thread %d\n", *(int *)arg);
}
return NULL;
}
int main()
{
pthread_t thread;
int arg = 1;
pthread_create(&thread, NULL, thread_func, &arg);
int i;
for (i = 0; i < 10; i++) {
printf("This is the main thread\n");
}
pthread_join(thread, NULL);
return 0;
}
在上面的例子中,我们创建了一个线程thread,并将传递给线程函数thread_func的参数设置为1。线程函数thread_func执行了10次,每次输出"This is thread 1",然后线程销毁。在主函数中,我们也执行了10次输出"This is the main thread",然后等待线程thread结束。
4. 线程同步
在多线程程序中,由于并发访问资源的问题,会导致程序出现意外的结果。因此,为了避免这种情况,必须要进行线程同步。
4.1 互斥锁
互斥锁是最常用的线程同步机制,它可以保证在同一时刻只有一个线程能够访问共享资源。在C语言中,可以使用pthread_mutex_lock函数和pthread_mutex_unlock函数来加锁和解锁互斥锁。使用方式如下:
#include <pthread.h>
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);
下面是一个使用互斥锁进行线程同步的例子:
#include <stdio.h>
#include <pthread.h>
int count;
pthread_mutex_t mutex;
void *thread_func(void *arg)
{
pthread_mutex_lock(&mutex);
int i;
for (i = 0; i < 10; i++) {
printf("This is thread %d\n", *(int *)arg);
count++;
}
pthread_mutex_unlock(&mutex);
return NULL;
}
int main()
{
pthread_t thread1, thread2;
int arg1 = 1, arg2 = 2;
pthread_mutex_init(&mutex, NULL);
pthread_create(&thread1, NULL, thread_func, &arg1);
pthread_create(&thread2, NULL, thread_func, &arg2);
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
printf("count = %d\n", count);
pthread_mutex_destroy(&mutex);
return 0;
}
在上面的例子中,我们定义了一个全局变量count,并使用pthread_mutex_lock函数和pthread_mutex_unlock函数对其进行了互斥访问。线程thread1和线程thread2都对该变量进行了10次加1操作。最后,我们输出count的结果为20。
4.2 条件变量
条件变量是在线程间实现等待/通知机制的一种方式。它允许一个或多个线程等待某个条件的发生,并在条件发生或者其他线程通知时被唤醒。在C语言中,可以使用pthread_cond_wait函数和pthread_cond_signal函数来实现条件变量。使用方式如下:
#include <pthread.h>
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
int pthread_cond_signal(pthread_cond_t *cond);
下面是一个使用条件变量进行线程同步的例子:
#include <stdio.h>
#include <pthread.h>
pthread_cond_t cond;
pthread_mutex_t mutex;
int flag = 0;
void *thread_func(void *arg)
{
pthread_mutex_lock(&mutex);
while (!flag)
pthread_cond_wait(&cond, &mutex);
printf("This is thread %d\n", *(int *)arg);
pthread_mutex_unlock(&mutex);
return NULL;
}
int main()
{
pthread_t thread1, thread2;
int arg1 = 1, arg2 = 2;
pthread_mutex_init(&mutex, NULL);
pthread_cond_init(&cond, NULL);
pthread_create(&thread1, NULL, thread_func, &arg1);
pthread_create(&thread2, NULL, thread_func, &arg2);
flag = 1;
pthread_cond_broadcast(&cond);
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
pthread_cond_destroy(&cond);
pthread_mutex_destroy(&mutex);
return 0;
}
在上面的例子中,我们定义了一个全局变量flag,并使用pthread_cond_wait函数和pthread_cond_signal函数来对线程进行等待和通知。线程thread1和线程thread2都被阻塞在pthread_cond_wait函数上,直到flag变为1时才能唤醒。最后,我们输出线程thread1和线程thread2的输出。由于使用了pthread_cond_broadcast函数进行广播通知,因此最终两个线程都会输出"This is thread 1"和"This is thread 2"。
5. 线程销毁
在线程执行完毕后,需要用pthread_join函数等待线程结束并释放资源。使用方式如下:
#include <pthread.h>
int pthread_join(pthread_t thread, void **retval);
下面是一个使用pthread_join等待线程结束的例子:
#include <stdio.h>
#include <pthread.h>
void *thread_func(void *arg)
{
int i;
for (i = 0; i < 10; i++) {
printf("This is thread %d\n", *(int *)arg);
}
return NULL;
}
int main()
{
pthread_t thread;
int arg = 1;
pthread_create(&thread, NULL, thread_func, &arg);
int i;
for (i = 0; i < 10; i++) {
printf("This is the main thread\n");
}
pthread_join(thread, NULL);
return 0;
}
在上面的例子中,我们使用pthread_join函数等待线程结束。如果不使用pthread_join函数等待线程结束,并且在程序退出前没有进行释放资源,则会造成内存泄漏。
6. 总结
通过本文的介绍,我们可以看到在linux系统下使用C语言编写多线程程序的基本方法、线程创建、线程同步和销毁。多线程编程是一项十分有用的技术,它可以提高程序的并发性和效率,并增加程序的响应速度和适应性。