Linux启动线程
在Linux操作系统中,线程是进程内独立的执行路径,是系统调度的基本单位,它们共享进程的资源,如内存和文件描述符,但有各自的计数器、寄存器和栈空间,本文将详细阐述在Linux下如何启动和管理线程。
一、Linux线程
线程是轻量级的执行单元,比进程创建和销毁的开销要小得多,每个线程都有自己的线程ID、程序计数器、寄存器集合以及栈空间,线程之间可以共享进程的资源,包括全局变量、静态变量和堆内存等,由于线程之间的切换成本较低,多线程编程可以显著提高系统的并发性和性能。
二、创建与启动线程
1. 使用pthread_create函数
pthread_create
是POSIX标准定义的创建新线程的函数,其原型如下:
#include <pthread.h> int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg);
thread
: 返回线程ID。
attr
: 设置线程的属性,通常设为NULL表示默认属性。
start_routine
: 线程启动后要执行的函数。
arg
: 传递给线程函数的参数。
示例代码:
#include <stdio.h> #include <stdlib.h> #include <pthread.h> void* print_message(void* arg) { char* message = (char*)arg; printf("%s ", message); return NULL; } int main() { pthread_t thread; char* message = "Hello from thread!"; int result = pthread_create(&thread, NULL, print_message, (void*)message); if (result != 0) { fprintf(stderr, "Thread creation failed "); return EXIT_FAILURE; } pthread_join(thread, NULL); // 等待线程结束 return EXIT_SUCCESS; }
编译命令:
gcc -o thread_example thread_example.c -lpthread
2. 使用fork+exec组合
通过fork
创建一个子进程,然后在子进程中调用exec
加载新的程序或线程库,从而启动线程。
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <pthread.h> void* thread_function(void* arg) { printf("Hello from new thread! "); return NULL; } int main() { pid_t pid = fork(); if (pid == 0) { // 子进程 pthread_t thread; pthread_create(&thread, NULL, thread_function, NULL); pthread_join(thread, NULL); exit(0); } else if (pid > 0) { // 父进程 printf("Hello from parent process! "); } else { // fork失败 fprintf(stderr, "Fork failed "); return EXIT_FAILURE; } return EXIT_SUCCESS; }
编译命令:
gcc -o fork_example fork_example.c -lpthread
3. 使用shell脚本启动线程
在Linux中,可以通过shell脚本的方式启动线程。
#!/bin/bash function start_routine { echo "Thread task" } 启动线程 start_routine & 脚本的其他任务 echo "Main task"
运行结果:
$ ./thread_script.sh Main task Thread task
三、线程同步与互斥
由于多个线程可能同时访问共享资源,因此需要进行线程同步和互斥控制,Linux提供了多种同步机制,包括互斥锁(mutex)、条件变量(condition variable)和信号量(semaphore)。
1. 互斥锁(Mutex)
互斥锁用于保护临界区,使得一次只有一个线程可以进入临界区,示例代码:
#include <stdio.h> #include <stdlib.h> #include <pthread.h> pthread_mutex_t lock; int counter = 0; void* increment_counter(void* arg) { for (int i = 0; i < 100000; ++i) { pthread_mutex_lock(&lock); ++counter; pthread_mutex_unlock(&lock); } return NULL; } int main() { pthread_t threads[10]; pthread_mutex_init(&lock, NULL); for (int i = 0; i < 10; ++i) { pthread_create(&threads[i], NULL, increment_counter, NULL); } for (int i = 0; i < 10; ++i) { pthread_join(threads[i], NULL); } printf("Counter: %d ", counter); pthread_mutex_destroy(&lock); return 0; }
编译命令:
gcc -o mutex_example mutex_example.c -lpthread
2. 条件变量(Condition Variable)
条件变量用于使线程阻塞,直到某个特定条件为真,示例代码:
#include <stdio.h> #include <stdlib.h> #include <pthread.h> pthread_cond_t cond; pthread_mutex_t lock; int ready = 0; void* consumer(void* arg) { pthread_mutex_lock(&lock); while (!ready) { pthread_cond_wait(&cond, &lock); } printf("Consumer: %d ", ready); pthread_mutex_unlock(&lock); return NULL; } void* producer(void* arg) { pthread_mutex_lock(&lock); ready = 1; pthread_cond_signal(&cond); pthread_mutex_unlock(&lock); return NULL; } int main() { pthread_t t1, t2; pthread_cond_init(&cond, NULL); pthread_mutex_init(&lock, NULL); pthread_create(&t1, NULL, consumer, NULL); pthread_create(&t2, NULL, producer, NULL); pthread_join(t1, NULL); pthread_join(t2, NULL); pthread_cond_destroy(&cond); pthread_mutex_destroy(&lock); return 0; }
编译命令:
gcc -o cond_example cond_example.c -lpthread
3. 信号量(Semaphore)
信号量用于控制对资源的访问数量,示例代码:
#include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <semaphore.h> sem_t sem; int shared_resource = 0; void* worker(void* arg) { sem_wait(&sem); // P操作,减少信号量值 // 临界区开始 shared_resource++; printf("Shared resource: %d ", shared_resource); sleep(1); // 模拟工作负载 // 临界区结束 sem_post(&sem); // V操作,增加信号量值 return NULL; } int main() { pthread_t threads[5]; sem_init(&sem, 0, 1); // 初始化信号量为1 for (int i = 0; i < 5; ++i) { pthread_create(&threads[i], NULL, worker, NULL); } for (int i = 0; i < 5; ++i) { pthread_join(threads[i], NULL); } sem_destroy(&sem); // 销毁信号量 return 0; }
编译命令:
gcc -o semaphore_example semaphore_example.c -lpthread -lrt -lsemaphore
四、线程终止与回收
线程可以通过以下三种方式终止:
1、从线程函数中返回:线程从启动例程中返回时会自动终止,示例:
void* thread_func(void* arg) { // 执行一些操作 return NULL; // 线程终止 }
2、调用pthread_exit:线程可以调用pthread_exit
来终止自身,示例:
void* thread_func(void* arg) { // 执行一些操作 pthread_exit(NULL); // 线程终止 }
3、取消线程:一个线程可以请求取消另一个线程,示例:
#include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <unistd.h> void* thread_func(void* arg) { while (1) { printf("Thread running... "); sleep(1); // 模拟工作负载 } return NULL; // 这一行实际上永远不会被执行到,因为线程会被取消 } int main() { pthread_t thread; pthread_create(&thread, NULL, thread_func, NULL); sleep(3); // 让线程运行一段时间 pthread_cancel(thread); // 请求取消线程 pthread_join(thread, NULL); // 等待线程结束并回收资源 return 0; }
以上内容就是解答有关“linux 启动线程”的详细内容了,我相信这篇文章可以为您解决一些疑惑,有任何问题欢迎留言反馈,谢谢阅读。