Linux操作系统提供了多种线程编程接口,其中最常用的是Pthreads。Pthreads是一套线程API,定义了线程的创建、控制、同步等操作。本文将介绍一些基本的Linux线程创建、退出等操作。
线程概述
线程是比进程更小的执行单元,在一个进程中可以有多个线程共享该进程的资源(内存、文件描述符、信号处理等)。线程是轻量级的,它们的切换成本非常低,因此在处理并发的I/O、计算密集型任务时使用线程往往比进程更加有效。
Linux线程采用POSIX标准,即Pthreads(POSIX Threads)来实现。Pthreads是一套线程API,定义了线程的创建、控制、同步等操作。头文件<pthread.h> 中包含了大部分Pthreads相关函数和数据类型。
线程创建
线程的创建需要调用pthread_create()函数。该函数的原型如下:
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg);
第一个参数指向pthread_t类型的指针,返回新创建线程的ID。
第二个参数指向一个结构体,用于设置线程属性。如果为NULL,则使用默认属性。
第三个参数是指向线程运行的函数指针。
第四个参数是传递给线程函数的参数。
下面是一个简单的创建线程的例子:
#include <pthread.h>
#include <stdio.h>
void *print_message(void *ptr);
int main() {
pthread_t thread;
char *message = "Hello BAI!";
int ret;
ret = pthread_create(&thread, NULL, print_message, (void*)message);
if (ret) {
printf("Error: unable to create thread, %d ", ret);
return -1;
}
printf("Main thread: Created thread with ID %u ", thread);
pthread_exit(NULL);
}
void *print_message(void *ptr) {
char *message = (char*) ptr;
printf("New thread: Message from new thread: %s ", message);
pthread_exit(NULL);
}
在这个例子中,通过调用pthread_create()函数创建了一个新的线程,并把print_message()作为线程的入口点。print_message()函数会输出一条消息。主线程会继续执行并最后调用pthread_exit()函数退出。
线程退出
线程退出有两种方式:自然退出和强制退出。
自然退出:线程执行完了所有的工作之后,会调用pthread_exit()函数退出。该函数的原型如下:
void pthread_exit(void *retval);
retval是线程的返回值。主线程可以通过调用pthread_join()函数获取线程的返回值。
强制退出:当线程执行过程中出现错误或者在特定条件下需要退出时,可以使用pthread_cancel()函数强制退出线程。该函数的原型如下:
int pthread_cancel(pthread_t thread);
thread是需要被取消的线程ID。
下面是一个简单的线程退出的例子:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
void *print_numbers(void *ptr);
int main() {
pthread_t thread;
int ret;
ret = pthread_create(&thread, NULL, print_numbers, NULL);
if (ret) {
printf("Error: unable to create thread, %d ", ret);
return -1;
}
// Wait for the thread to exit
pthread_join(thread, NULL);
printf("Main thread: Thread exited successfully! ");
pthread_exit(NULL);
}
void *print_numbers(void *ptr) {
int i;
for (i = 0; i < 10; i++) {
printf("New thread: %d ", i);
sleep(1);
}
pthread_exit(NULL);
}
在这个例子中,通过调用pthread_create()函数创建了一个新的线程,并把print_numbers()作为线程的入口点。print_numbers()函数会输出10个数字并且每隔1秒钟打印一次。主线程调用pthread_join()等待新线程退出,当新线程退出时,主线程继续执行并调用pthread_exit()函数退出。
线程同步
多个线程共享进程中的资源,因此往往需要进行同步操作以避免数据竞争和死锁等问题。Pthreads提供了多种同步机制,如:互斥量、条件变量等。
互斥量:互斥量是一种用于保护共享资源的同步原语。它确保同一时间内只有一个线程可以访问共享资源。Pthreads提供了多种函数用于创建、销毁、加锁和解锁互斥量。下面是一个简单的互斥量使用的例子:
c
#include <stdio.h>
#include <pthread.h>
#define MAX_COUNT 1000000
int count = 0;
pthread_mutex_t mutex;
void *increment_count(void *arg) {
int i;
for (i = 0; i < MAX_COUNT; i++) {
pthread_mutex_lock(&mutex);
count++;
pthread_mutex_unlock(&mutex);
}
pthread_exit(NULL);
}
int main() {
pthread_t thread1, thread2;
int ret;
pthread_mutex_init(&mutex, NULL);
ret = pthread_create(&thread1, NULL, increment_count, NULL);
if (ret) {
printf("Error: unable to create thread, %d ", ret);
return -1;
}
ret = pthread_create(&thread2, NULL, increment_count, NULL);
if (ret) {
printf("Error: unable to create thread, %d ", ret);
return -1;
}
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
pthread_mutex_destroy(&mutex);
printf("Count: %d ", count);
pthread_exit(NULL);
}
在这个例子中,通过使用互斥量保护count变量,两个线程分别对count变量进行1000000次自增操作。在每次自增之前,线程会调用pthread_mutex_lock()函数获取互斥量,自增操作完成后再调用pthread_mutex_unlock()函数释放互斥量。
条件变量:条件变量是一种用于控制线程运行顺序的同步原语。它使得线程可以等待某个条件成立才能继续执行。Pthreads提供了多种函数用于创建、销毁、等待和唤醒条件变量。下面是一个简单的条件变量使用的例子:
c
#include <stdio.h>
#include <pthread.h>
#define MAX_COUNT 5
int count = 0;
pthread_mutex_t mutex;
pthread_cond_t cond;
void *print_numbers(void *arg) {
int i;
for (i = 0; i < MAX_COUNT; i++) {
pthread_mutex_lock(&mutex);
while (count % 2 != 0) {
pthread_cond_wait(&cond, &mutex);
}
printf("%d ", i);
count++;
pthread_mutex_unlock(&mutex);
pthread_cond_signal(&cond);
}
pthread_exit(NULL);
}
int main() {
pthread_t thread;
int ret;
pthread_mutex_init(&mutex, NULL);
pthread_cond_init(&cond, NULL);
ret = pthread_create(&thread, NULL, print_numbers, NULL);
if (ret) {
printf("Error: unable to create thread, %d ", ret);
return -1;
}
int i;
for (i = 0; i < MAX_COUNT; i++) {
pthread_mutex_lock(&mutex);
while (count % 2 == 0) {
pthread_cond_wait(&cond, &mutex);
}
printf("%d ", i);
count++;
pthread_mutex_unlock(&mutex);
pthread_cond_signal(&cond);
}
pthread_join(thread, NULL);
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&cond);
pthread_exit(NULL);
}