「教程」linux下C语言多线程入门指南

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语言编写多线程程序的基本方法、线程创建、线程同步和销毁。多线程编程是一项十分有用的技术,它可以提高程序的并发性和效率,并增加程序的响应速度和适应性。

操作系统标签