Linux线程的创建方式是什么

发布时间:2023-03-23 11:57:26 作者:iii
来源:亿速云 阅读:173

Linux线程的创建方式是什么

目录

  1. 引言
  2. 线程的基本概念
  3. Linux线程模型
  4. 线程的创建方式
  5. 线程的同步与互斥
  6. 线程的销毁与回收
  7. 线程的调度与优先级
  8. 线程的取消与清理
  9. 线程的局部存储
  10. 线程池的实现
  11. 线程的调试与性能分析
  12. 总结

引言

在现代操作系统中,线程是并发执行的基本单位。Linux多任务操作系统,提供了丰富的线程管理机制。本文将详细介绍Linux中线程的创建方式,并探讨线程的同步、调度、销毁等相关内容。

线程的基本概念

2.1 什么是线程

线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一个进程可以包含多个线程,这些线程共享进程的资源,如内存空间、文件描述符等。

2.2 线程与进程的区别

Linux线程模型

3.1 POSIX线程模型

POSIX线程(Pthreads)是IEEE POSIX 1003.1c标准定义的线程接口。Linux通过libpthread库实现了POSIX线程模型。

3.2 Linux线程库

Linux提供了多种线程库,如libpthreadlibc等。libpthread是最常用的线程库,提供了丰富的线程管理函数。

线程的创建方式

4.1 使用pthread_create函数创建线程

pthread_create是POSIX线程库中用于创建线程的函数。其原型如下:

int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
                   void *(*start_routine) (void *), void *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);
}

4.2 使用clone系统调用创建线程

clone是Linux系统调用,用于创建一个新的进程或线程。其原型如下:

int clone(int (*fn)(void *), void *child_stack, int flags, void *arg, ...
          /* pid_t *ptid, void *newtls, pid_t *ctid */ );

示例代码:

#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;
}

4.3 使用forkexec创建线程

forkexec通常用于创建新的进程,但通过一些技巧,也可以用于创建线程。不过,这种方式并不常见,因为fork会复制整个进程的地址空间,而线程共享进程的地址空间。

线程的同步与互斥

5.1 互斥锁

互斥锁(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;
}

5.2 条件变量

条件变量(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;
}

5.3 信号量

信号量(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;
}

线程的销毁与回收

6.1 使用pthread_exit退出线程

pthread_exit用于显式退出线程。其原型如下:

void pthread_exit(void *retval);

6.2 使用pthread_join回收线程

pthread_join用于等待线程结束并回收资源。其原型如下:

int pthread_join(pthread_t thread, void **retval);

6.3 使用pthread_detach分离线程

pthread_detach用于分离线程,使其在结束时自动回收资源。其原型如下:

int pthread_detach(pthread_t thread);

线程的调度与优先级

7.1 线程调度策略

Linux支持多种线程调度策略,如SCHED_FIFOSCHED_RRSCHED_OTHER等。

7.2 线程优先级

线程优先级可以通过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, &param);
    printf("Thread priority: %d\n", param.sched_priority);

    param.sched_priority = 10;
    pthread_setschedparam(thread, SCHED_FIFO, &param);

    pthread_join(thread, NULL);
    return 0;
}

线程的取消与清理

8.1 线程取消

线程取消(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;
}

8.2 线程清理

线程清理(Thread Cleanup)用于在线程退出时执行清理操作。POSIX线程库提供了pthread_cleanup_pushpthread_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;
}

线程的局部存储

9.1 线程局部存储的概念

线程局部存储(Thread Local Storage, TLS)允许每个线程拥有自己的变量副本。

9.2 使用pthread_key_create创建线程局部存储

pthread_key_create用于创建线程局部存储键。其原型如下:

int pthread_key_create(pthread_key_t *key, void (*destructor)(void*));

示例代码:

#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;
}

线程池的实现

10.1 线程池的概念

线程池(Thread Pool)是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务。

10.2 线程池的实现方式

线程池的实现通常包括任务队列、线程管理、任务调度等部分。

示例代码:

#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;
}

线程的调试与性能分析

11.1 线程调试工具

常用的线程调试工具有gdbvalgrind等。

11.2 线程性能分析工具

常用的线程性能分析工具有perfgprof等。

总结

本文详细介绍了Linux中线程的创建方式,包括使用pthread_createcloneforkexec等方法。此外,还探讨了线程的同步、调度、销毁、局部存储、线程池等相关内容。通过本文的学习,读者应能够掌握Linux线程的基本概念和操作,并能够在实际项目中应用这些知识。

推荐阅读:
  1. linux 命令行下怎么使用android sdk 以及ndk
  2. python+unittest在linux与windows环境的使用区别

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

linux

上一篇:SpringBoot怎么整合Redis实现序列化存储Java对象

下一篇:Shell脚本位置参数如何使用

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》