1.线程的概念
在计算机领域,线程是进程中的一个执行单元。一个进程可以包含多个线程,而每个线程都可以独立执行任务。线程与进程不同的是,线程共享进程的资源,包括内存空间、文件句柄和打开的文件等。同时,线程之间的切换开销相对较小,所以多线程的并行执行可以提高程序的效率。
2.线程的状态
线程可以处于以下几种不同的状态:
就绪状态
当线程被创建时,它处于就绪状态,表示该线程已经准备好执行,只等待系统调度。
运行状态
当线程被系统调度执行时,它处于运行状态。
阻塞状态
当线程需要等待某个事件发生时,它会进入阻塞状态,此时线程不会占用系统资源,直到等待的事件发生才会被唤醒。
终止状态
当线程完成了它的任务或者出现了不可恢复的错误时,线程会进入终止状态。
3.linux下线程的创建和终止
线程的创建
在Linux下,可以使用pthread库来创建和管理线程。pthread是POSIX线程的缩写,提供了一系列的函数来操作线程。
#include <pthread.h>
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg);
pthread_create函数用于创建一个新的线程。它接受四个参数:
thread:一个指向pthread_t类型的指针,用于存储新创建的线程的标识符。
attr:一个指向pthread_attr_t类型的指针,用于指定新线程的属性。可以使用默认值NULL。
start_routine:一个指向函数的指针,该函数是新线程的入口。该函数的返回值和参数都是void*类型。
arg:用于传递给start_routine函数的参数。
以下是一个创建线程的示例:
#include <stdio.h>
#include <pthread.h>
void *print_message(void *message) {
char *msg = (char *)message;
printf("%s\n", msg);
}
int main() {
pthread_t thread;
int ret = pthread_create(&thread, NULL, print_message, "Hello, World!");
if (ret != 0) {
printf("Failed to create thread\n");
return 1;
}
pthread_join(thread, NULL); //等待线程结束
return 0;
}
在上面的示例中,使用pthread_create函数创建了一个新线程,并传递了一个字符串作为参数。新线程的入口函数print_message接收到参数后,将其打印出来。
线程的终止
线程的终止可以通过以下几种方式来实现:
返回
线程可以通过从入口函数返回来终止。
#include <stdio.h>
#include <pthread.h>
void *countdown(void *arg) {
for (int i = 10; i > 0; i--) {
printf("%d\n", i);
}
return NULL;
}
int main() {
pthread_t thread;
pthread_create(&thread, NULL, countdown, NULL);
pthread_join(thread, NULL); //等待线程结束
printf("Countdown finished\n");
return 0;
}
上面的示例中,线程的入口函数countdown倒计时从10到1,然后通过返回NULL来终止线程。在主线程中使用pthread_join函数来等待线程的结束。
pthread_exit函数
线程可以调用pthread_exit函数来终止自己。
#include <stdio.h>
#include <pthread.h>
void *countdown(void *arg) {
for (int i = 10; i > 0; i--) {
printf("%d\n", i);
}
pthread_exit(NULL);
}
int main() {
pthread_t thread;
pthread_create(&thread, NULL, countdown, NULL);
pthread_join(thread, NULL); //等待线程结束
printf("Countdown finished\n");
return 0;
}
上面的示例中,通过调用pthread_exit(NULL)来终止线程。在主线程中使用pthread_join函数来等待线程的结束。
pthread_cancel函数
线程可以被其他线程通过调用pthread_cancel函数来终止。
#include <stdio.h>
#include <pthread.h>
void *countdown(void *arg) {
for (int i = 10; i > 0; i--) {
printf("%d\n", i);
sleep(1);
}
return NULL;
}
int main() {
pthread_t thread;
pthread_create(&thread, NULL, countdown, NULL);
sleep(5); //等待5秒
pthread_cancel(thread); //终止线程
pthread_join(thread, NULL); //等待线程结束
printf("Countdown finished\n");
return 0;
}
上面的示例中,通过调用pthread_cancel函数来终止线程。在主线程中使用pthread_join函数来等待线程的结束。
4.如何停止线程
在Linux中,没有像Windows系统中的TerminateThread函数那样直接终止线程的函数。但是,我们可以通过其他方式来停止线程的执行。
退出线程
线程可以通过从入口函数返回、调用pthread_exit函数或者响应pthread_cancel信号来退出。
以下是一个示例:
#include <stdio.h>
#include <pthread.h>
pthread_mutex_t lock;
int flag = 0;
void *countdown(void *arg) {
while (1) {
pthread_mutex_lock(&lock);
if (flag) {
pthread_mutex_unlock(&lock);
break;
}
pthread_mutex_unlock(&lock);
printf("Counting...\n");
sleep(1);
}
return NULL;
}
int main() {
pthread_t thread;
pthread_mutex_init(&lock, NULL);
pthread_create(&thread, NULL, countdown, NULL);
sleep(5);
pthread_mutex_lock(&lock);
flag = 1;
pthread_mutex_unlock(&lock);
pthread_join(thread, NULL);
printf("Countdown stopped\n");
pthread_mutex_destroy(&lock);
return 0;
}
在上面的示例中,使用一个flag变量来控制线程的退出。线程中通过轮询检查flag变量的值来判断是否退出。在主线程中,等待5秒后将flag变量设置为1,从而终止线程的执行。
发送信号
在Linux中,线程可以通过signal函数来设置信号处理函数,当接收到终止线程的信号时,线程可以在信号处理函数中退出。
以下是一个示例:
#include <stdio.h>
#include <pthread.h>
#include <signal.h>
void signal_handler(int signum) {
printf("Signal received, exiting\n");
pthread_exit(NULL);
}
void *countdown(void *arg) {
signal(SIGUSR1, signal_handler); //设置信号处理函数
while (1) {
printf("Counting...\n");
sleep(1);
}
return NULL;
}
int main() {
pthread_t thread;
pthread_create(&thread, NULL, countdown, NULL);
sleep(5);
pthread_kill(thread, SIGUSR1); //发送信号终止线程
pthread_join(thread, NULL);
printf("Countdown stopped\n");
return 0;
}
在上面的示例中,设置了一个SIGUSR1信号处理函数,当收到该信号时,线程将调用pthread_exit函数退出。在主线程中,等待5秒后发送SIGUSR1信号来终止线程的执行。
5.总结
本文介绍了Linux下线程的概念、状态和创建终止方法。线程的创建可以使用pthread库提供的pthread_create函数来实现,线程的终止可以通过从入口函数返回、调用pthread_exit函数或者响应信号来实现。在实际开发中,根据实际需求选择合适的方法来停止线程的执行。