蓝桉云顶

Good Luck To You!

如何在Linux系统中启动一个新线程?

在 Linux 系统中,可以通过 pthread_create 函数来启动一个新的线程。

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 启动线程”的详细内容了,我相信这篇文章可以为您解决一些疑惑,有任何问题欢迎留言反馈,谢谢阅读。

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

«    2024年11月    »
123
45678910
11121314151617
18192021222324
252627282930
控制面板
您好,欢迎到访网站!
  查看权限
网站分类
搜索
最新留言
文章归档
网站收藏
友情链接