您好,登录后才能下订单哦!
在现代操作系统中,线程是并发执行的基本单位。Linux多任务操作系统,提供了丰富的线程管理机制。本文将详细介绍Linux中线程的创建方式,并探讨线程的同步、调度、销毁等相关内容。
线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一个进程可以包含多个线程,这些线程共享进程的资源,如内存空间、文件描述符等。
POSIX线程(Pthreads)是IEEE POSIX 1003.1c标准定义的线程接口。Linux通过libpthread
库实现了POSIX线程模型。
Linux提供了多种线程库,如libpthread
、libc
等。libpthread
是最常用的线程库,提供了丰富的线程管理函数。
pthread_create
函数创建线程pthread_create
是POSIX线程库中用于创建线程的函数。其原型如下:
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg);
thread
:指向线程标识符的指针。attr
:线程属性,通常为NULL
。start_routine
:线程执行的函数。arg
:传递给线程函数的参数。示例代码:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
void *print_message_function(void *ptr) {
char *message;
message = (char *) ptr;
printf("%s \n", message);
pthread_exit(NULL);
}
int main() {
pthread_t thread1, thread2;
char *message1 = "Thread 1";
char *message2 = "Thread 2";
int iret1, iret2;
iret1 = pthread_create(&thread1, NULL, print_message_function, (void*) message1);
iret2 = pthread_create(&thread2, NULL, print_message_function, (void*) message2);
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
printf("Thread 1 returns: %d\n", iret1);
printf("Thread 2 returns: %d\n", iret2);
pthread_exit(NULL);
}
clone
系统调用创建线程clone
是Linux系统调用,用于创建一个新的进程或线程。其原型如下:
int clone(int (*fn)(void *), void *child_stack, int flags, void *arg, ...
/* pid_t *ptid, void *newtls, pid_t *ctid */ );
fn
:子进程/线程执行的函数。child_stack
:子进程/线程的栈空间。flags
:控制子进程/线程的行为。arg
:传递给子进程/线程的参数。示例代码:
#define _GNU_SOURCE
#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
#define STACK_SIZE (1024 * 1024)
static int child_func(void *arg) {
printf("Child thread running\n");
return 0;
}
int main() {
void *stack = malloc(STACK_SIZE);
if (stack == NULL) {
perror("malloc");
exit(EXIT_FLURE);
}
pid_t pid = clone(child_func, stack + STACK_SIZE, CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_THREAD, NULL);
if (pid == -1) {
perror("clone");
exit(EXIT_FLURE);
}
waitpid(pid, NULL, 0);
printf("Child thread exited\n");
free(stack);
return 0;
}
fork
和exec
创建线程fork
和exec
通常用于创建新的进程,但通过一些技巧,也可以用于创建线程。不过,这种方式并不常见,因为fork
会复制整个进程的地址空间,而线程共享进程的地址空间。
互斥锁(Mutex)用于保护共享资源,防止多个线程同时访问。POSIX线程库提供了pthread_mutex_t
类型和相关函数。
示例代码:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int counter = 0;
void *increment_counter(void *arg) {
for (int i = 0; i < 100000; i++) {
pthread_mutex_lock(&mutex);
counter++;
pthread_mutex_unlock(&mutex);
}
pthread_exit(NULL);
}
int main() {
pthread_t thread1, thread2;
pthread_create(&thread1, NULL, increment_counter, NULL);
pthread_create(&thread2, NULL, increment_counter, NULL);
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
printf("Counter value: %d\n", counter);
return 0;
}
条件变量(Condition Variable)用于线程间的同步。POSIX线程库提供了pthread_cond_t
类型和相关函数。
示例代码:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
int ready = 0;
void *producer(void *arg) {
pthread_mutex_lock(&mutex);
ready = 1;
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
pthread_exit(NULL);
}
void *consumer(void *arg) {
pthread_mutex_lock(&mutex);
while (!ready) {
pthread_cond_wait(&cond, &mutex);
}
printf("Consumer: ready is %d\n", ready);
pthread_mutex_unlock(&mutex);
pthread_exit(NULL);
}
int main() {
pthread_t thread1, thread2;
pthread_create(&thread1, NULL, consumer, NULL);
pthread_create(&thread2, NULL, producer, NULL);
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
return 0;
}
信号量(Semaphore)是一种更通用的同步机制。POSIX线程库提供了sem_t
类型和相关函数。
示例代码:
#include <semaphore.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
sem_t semaphore;
void *thread_func(void *arg) {
sem_wait(&semaphore);
printf("Thread %ld is running\n", (long)arg);
sem_post(&semaphore);
pthread_exit(NULL);
}
int main() {
pthread_t threads[5];
sem_init(&semaphore, 0, 1);
for (long i = 0; i < 5; i++) {
pthread_create(&threads[i], NULL, thread_func, (void *)i);
}
for (int i = 0; i < 5; i++) {
pthread_join(threads[i], NULL);
}
sem_destroy(&semaphore);
return 0;
}
pthread_exit
退出线程pthread_exit
用于显式退出线程。其原型如下:
void pthread_exit(void *retval);
retval
:线程的返回值。pthread_join
回收线程pthread_join
用于等待线程结束并回收资源。其原型如下:
int pthread_join(pthread_t thread, void **retval);
thread
:线程标识符。retval
:指向线程返回值的指针。pthread_detach
分离线程pthread_detach
用于分离线程,使其在结束时自动回收资源。其原型如下:
int pthread_detach(pthread_t thread);
thread
:线程标识符。Linux支持多种线程调度策略,如SCHED_FIFO
、SCHED_RR
、SCHED_OTHER
等。
线程优先级可以通过pthread_setschedparam
函数设置。
示例代码:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <sched.h>
void *thread_func(void *arg) {
printf("Thread is running\n");
pthread_exit(NULL);
}
int main() {
pthread_t thread;
struct sched_param param;
int policy;
pthread_create(&thread, NULL, thread_func, NULL);
pthread_getschedparam(thread, &policy, ¶m);
printf("Thread priority: %d\n", param.sched_priority);
param.sched_priority = 10;
pthread_setschedparam(thread, SCHED_FIFO, ¶m);
pthread_join(thread, NULL);
return 0;
}
线程取消(Thread Cancellation)允许一个线程请求另一个线程终止。POSIX线程库提供了pthread_cancel
函数。
示例代码:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void *thread_func(void *arg) {
while (1) {
printf("Thread is running\n");
sleep(1);
}
pthread_exit(NULL);
}
int main() {
pthread_t thread;
pthread_create(&thread, NULL, thread_func, NULL);
sleep(3);
pthread_cancel(thread);
pthread_join(thread, NULL);
printf("Thread has been canceled\n");
return 0;
}
线程清理(Thread Cleanup)用于在线程退出时执行清理操作。POSIX线程库提供了pthread_cleanup_push
和pthread_cleanup_pop
函数。
示例代码:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
void cleanup_func(void *arg) {
printf("Cleanup function is called\n");
}
void *thread_func(void *arg) {
pthread_cleanup_push(cleanup_func, NULL);
printf("Thread is running\n");
pthread_exit(NULL);
pthread_cleanup_pop(0);
}
int main() {
pthread_t thread;
pthread_create(&thread, NULL, thread_func, NULL);
pthread_join(thread, NULL);
return 0;
}
线程局部存储(Thread Local Storage, TLS)允许每个线程拥有自己的变量副本。
pthread_key_create
创建线程局部存储pthread_key_create
用于创建线程局部存储键。其原型如下:
int pthread_key_create(pthread_key_t *key, void (*destructor)(void*));
key
:指向线程局部存储键的指针。destructor
:析构函数,用于在线程退出时释放资源。示例代码:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
pthread_key_t key;
void destructor(void *value) {
free(value);
}
void *thread_func(void *arg) {
int *value = malloc(sizeof(int));
*value = 42;
pthread_setspecific(key, value);
printf("Thread local value: %d\n", *(int *)pthread_getspecific(key));
pthread_exit(NULL);
}
int main() {
pthread_t thread;
pthread_key_create(&key, destructor);
pthread_create(&thread, NULL, thread_func, NULL);
pthread_join(thread, NULL);
pthread_key_delete(key);
return 0;
}
线程池(Thread Pool)是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务。
线程池的实现通常包括任务队列、线程管理、任务调度等部分。
示例代码:
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <queue>
#define THREAD_POOL_SIZE 4
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
std::queue<void (*)(void *)> task_queue;
void *worker_thread(void *arg) {
while (1) {
pthread_mutex_lock(&mutex);
while (task_queue.empty()) {
pthread_cond_wait(&cond, &mutex);
}
void (*task)(void *) = task_queue.front();
task_queue.pop();
pthread_mutex_unlock(&mutex);
task(NULL);
}
return NULL;
}
void task_func(void *arg) {
printf("Task is running\n");
}
int main() {
pthread_t threads[THREAD_POOL_SIZE];
for (int i = 0; i < THREAD_POOL_SIZE; i++) {
pthread_create(&threads[i], NULL, worker_thread, NULL);
}
for (int i = 0; i < 10; i++) {
pthread_mutex_lock(&mutex);
task_queue.push(task_func);
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
}
sleep(1);
return 0;
}
常用的线程调试工具有gdb
、valgrind
等。
常用的线程性能分析工具有perf
、gprof
等。
本文详细介绍了Linux中线程的创建方式,包括使用pthread_create
、clone
、fork
和exec
等方法。此外,还探讨了线程的同步、调度、销毁、局部存储、线程池等相关内容。通过本文的学习,读者应能够掌握Linux线程的基本概念和操作,并能够在实际项目中应用这些知识。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。