C语言线程详解,及Linux中的一些相关命令

打印 上一主题 下一主题

主题 661|帖子 661|积分 1983


以下是关于C语言中线程的具体解说,包含线程的创建、管理、同步、停止等方面的内容,并增加了对线程和历程的区别与接洽的解说,以及相关知识的扩展。同时,添加了Linux中对线程和历程相关操作的命令。
1. 线程的基本概念



  • 线程:线程是历程中的一个执行流,多个线程共享同一历程的资源(如内存、文件描述符等),可以并发执行。
  • 历程:历程是操作体系分配资源的基本单位,每个历程都有自己的地址空间。线程是轻量级的历程。
2. 线程与历程的区别与接洽

2.1 区别


  • 资源分配

    • 历程:每个历程都有独立的地址空间和资源,历程之间的通信必要通过IPC(历程间通信)机制,如管道、消息队列、共享内存等。
    • 线程:线程共享同一历程的地址空间和资源,线程之间的通信相对简单,可以直接访问共享数据。

  • 创建和销毁

    • 历程:创建和销毁历程的开销较大,因为必要分配和管理独立的资源。
    • 线程:创建和销毁线程的开销较小,因为线程共享历程的资源。

  • 调治

    • 历程:操作体系对历程的调治相对复杂,涉及到历程的状态管理和上下文切换。
    • 线程:线程的调治相对简单,线程的上下文切换速度更快。

  • 稳定性

    • 历程:一个历程的瓦解不会影响其他历程的运行。
    • 线程:一个线程的瓦解可能导致整个历程的瓦解,因为所有线程共享同一历程的资源。

2.2 接洽



  • 共享资源:线程是历程的一部分,多个线程可以共享同一历程的资源,如内存和文件描述符。
  • 并发执行:线程和历程都可以实现并发执行,提升步伐的性能和响应能力。
  • 调治机制:操作体系对线程和历程的调治机制有相似之处,都是通过调治算法来管理执行。
3. 线程的底层实现

线程的底层实现依靠于操作体系的调治和管理机制。差别的操作体系可能会有差别的线程实现方式,但通常包罗以下几个方面:
3.1 线程调治

操作体系利用调治算法来管理线程的执行。常见的调治算法包罗:


  • 先来先服务(FCFS):按照线程到达的次序举行调治。
  • 时间片轮转(Round Robin):为每个线程分配一个时间片,时间片用完后切换到下一个线程。
  • 优先级调治:根据线程的优先级举行调治,高优先级线程优先执行。
3.2 线程上下文切换

当操作体系必要切换执行的线程时,会举行上下文切换。上下文切换的过程包罗:

  • 保存当前线程的上下文(寄存器、步伐计数器等)。
  • 加载下一个线程的上下文。
  • 更新调治信息。
上下文切换是一个相对昂贵的操作,频仍的上下文切换会影响步伐的性能。
3.3 线程栈

每个线程都有自己的栈空间,用于存储局部变量、函数参数和返回地址。线程栈的大小可以在创建线程时指定,通常默认大小为1MB。
4. 线程的创建

在C语言中,线程通常通过POSIX线程(pthread)库来创建和管理。以下是创建线程的基本步骤:
4.1 包含头文件

在利用pthread库之前,必要包含相应的头文件:
  1. #include <pthread.h>
复制代码
4.2 定义线程函数

线程函数必须返回void*范例,并继承一个void*范例的参数。这个参数可以用来传递数据给线程。
  1. void* thread_function(void* arg) {
  2.     int* num = (int*)arg; // 将参数转换为整数指针
  3.     printf("Thread number: %d\n", *num);
  4.     return NULL;
  5. }
复制代码
4.3 创建线程

利用pthread_create函数创建线程。该函数的原型如下:
  1. int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void*), void *arg);
复制代码


  • thread:指向线程标识符的指针。
  • attr:线程属性,通常为NULL。
  • start_routine:线程执行的函数。
  • arg:传递给线程函数的参数。
示例代码:
  1. int main() {
  2.     pthread_t thread_id;
  3.     int thread_num = 1; // 线程参数
  4.     pthread_create(&thread_id, NULL, thread_function, &thread_num);
  5.     pthread_join(thread_id, NULL); // 等待线程结束
  6.     return 0;
  7. }
复制代码
5. 线程的同步

由于多个线程可能会同时访问共享资源,因此必要同步机制来避免数据竞争。常用的同步机制包罗:
5.1 互斥锁(Mutex)

互斥锁用于保护共享资源,确保同一时间只有一个线程可以访问该资源。利用互斥锁的步骤如下:

  • 初始化互斥锁
    1. pthread_mutex_t mutex;
    2. pthread_mutex_init(&mutex, NULL);
    复制代码
  • 加锁息争锁
    1. pthread_mutex_lock(&mutex);
    2. // 访问共享资源
    3. pthread_mutex_unlock(&mutex);
    复制代码
  • 销毁互斥锁
    1. pthread_mutex_destroy(&mutex);
    复制代码
示例代码:
  1. #include <stdio.h>#include <pthread.h>
  2. pthread_mutex_t mutex;void* thread_function(void* arg) {    pthread_mutex_lock(&mutex);    printf("Thread is accessing shared resource.\n");    pthread_mutex_unlock(&mutex);    return NULL;}int main() {    pthread_t thread_id[5];    pthread_mutex_init(&mutex, NULL);        for (int i = 0; i < 5; i++) {        pthread_create(&thread_id[i], NULL, thread_function, NULL);    }        for (int i = 0; i < 5; i++) {        pthread_join(thread_id[i], NULL);    }        pthread_mutex_destroy(&mutex);
  3.     return 0;}
复制代码
5.2 条件变量(Condition Variables)

条件变量用于线程之间的信号传递,允许一个线程等候某个条件的发生。利用条件变量的步骤如下:

  • 初始化条件变量
    1. pthread_cond_t cond;
    2. pthread_cond_init(&cond, NULL);
    复制代码
  • 等候条件
    1. pthread_cond_wait(&cond, &mutex);
    复制代码
  • 发送信号
    1. pthread_cond_signal(&cond);
    复制代码
  • 销毁条件变量
    1. pthread_cond_destroy(&cond);
    复制代码
示例代码:
  1. #include <stdio.h>#include <pthread.h>
  2. pthread_mutex_t mutex;pthread_cond_t cond;int ready = 0;void* thread_function(void* arg) {    pthread_mutex_lock(&mutex);    while (!ready) {        pthread_cond_wait(&cond, &mutex);
  3.     }    printf("Thread is running after condition is met.\n");    pthread_mutex_unlock(&mutex);    return NULL;}int main() {    pthread_t thread_id;    pthread_mutex_init(&mutex, NULL);    pthread_cond_init(&cond, NULL);        pthread_create(&thread_id, NULL, thread_function, NULL);        // 模仿一些工作    sleep(1);        pthread_mutex_lock(&mutex);    ready = 1; // 设置条件    pthread_cond_signal(&cond);
  4. // 发送信号    pthread_mutex_unlock(&mutex);        pthread_join(thread_id, NULL);    pthread_mutex_destroy(&mutex);
  5.     pthread_cond_destroy(&cond);
  6.     return 0;}
复制代码
6. 线程的优先级

在C语言中,线程的优先级可以通过pthread_setschedparam函数设置。优先级的管理依靠于操作体系的调治策略。以下是设置线程优先级的示例:
  1. #include <pthread.h>
  2. #include <sched.h>void* thread_function(void* arg) {    // 线程执行的代码    return NULL;}int main() {    pthread_t thread_id;    pthread_create(&thread_id, NULL, thread_function, NULL);        struct sched_param param;    param.sched_priority = 10; // 设置优先级    pthread_setschedparam(thread_id, SCHED_FIFO, &param);        pthread_join(thread_id, NULL);    return 0;}
复制代码
7. 线程的停止

线程可以通过返回线程函数或调用pthread_exit函数来停止。利用pthread_cancel可以哀求取消线程,但必要注意线程的状态。
7.1 线程退出

  1. void* thread_function(void* arg) {
  2.     // 执行一些操作
  3.     pthread_exit(NULL); // 线程退出
  4. }
复制代码
7.2 取消线程

  1. pthread_cancel(thread_id); // 请求取消线程
复制代码
8. 示例代码

以下是一个完备的示例,展示了怎样创建和利用线程,包罗互斥锁和条件变量的利用:
  1. #include <stdio.h>#include <pthread.h>
  2. #include <unistd.h>pthread_mutex_t mutex;pthread_cond_t cond;int ready = 0;void* thread_function(void* arg) {    pthread_mutex_lock(&mutex);    while (!ready) {        pthread_cond_wait(&cond, &mutex);
  3.     }    printf("Thread is running after condition is met.\n");    pthread_mutex_unlock(&mutex);    return NULL;}int main() {    pthread_t thread_id;    pthread_mutex_init(&mutex, NULL);    pthread_cond_init(&cond, NULL);        pthread_create(&thread_id, NULL, thread_function, NULL);        // 模仿一些工作    sleep(1);        pthread_mutex_lock(&mutex);    ready = 1; // 设置条件    pthread_cond_signal(&cond);
  4. // 发送信号    pthread_mutex_unlock(&mutex);        pthread_join(thread_id, NULL);    pthread_mutex_destroy(&mutex);
  5.     pthread_cond_destroy(&cond);
  6.     return 0;}
复制代码
9. Linux中对线程和历程相关操作的命令

9.1 查看历程



  • ps aux:查看当前体系中所有历程的信息。
  • top:实时查看体系中历程的资源利用情况。
9.2 查看线程



  • ps -eLf:查看体系中所有线程的信息。
  • top -H:在top命令中表现线程信息。
9.3 杀死历程



  • kill <pid>:发送信号停止指定历程。
  • kill -9 <pid>:逼迫停止指定历程。
9.4 杀死线程



  • 线程通常通过停止其所属的历程来结束,利用kill命令时指定历程ID(PID)即可。
9.5 创建历程



  • fork():在C语言中利用fork()体系调用创建新历程。
9.6 创建线程



  • pthread_create():在C语言中利用pthread_create()函数创建新线程。
10. 总结

C语言中的线程提供了并发执行的能力,通过利用pthread库,可以创建、管理和同步线程。明白线程的基本概念和操作是编写高效多线程步伐的关键。线程与历程的区别在于资源分配、创建和销毁的开销、调治复杂性等方面,而它们之间的接洽则体如今共享资源和并发执行的能力上。线程的底层实现涉及调治、上下文切换和线程栈等方面,掌握这些知识有助于更深入地明白多线程编程的性能和行为。线程的同步机制(如互斥锁和条件变量)是确保数据划一性和避免竞争条件的紧张工具。Linux中提供了多种命令来管理和监控历程与线程,资助开发者更好地举行体系调试和性能优化。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

愛在花開的季節

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表