Linux实验七:线程管理


一、实验目的

1、深入理解线程模型相关概念;
2、掌握线程相关的数据结构及常用的函数。

二、实验内容

线程A向终端打印字符 “1”,线程B向终端打印字符 “2”。要求使用 POSIX 线程和信号量实现以下功能:向终端打印 “1 2 1 2”。

三、实验环境

虚拟机软件:VMware 16 Pro
Linux操作系统版本:CentOS-7-64位

四、参考代码

#include<semaphore.h>
#include<pthread.h>
#include<stdio.h>
#include<stdlib.h>

void* funA(void*);
void* funB(void*);

sem_t sem1,sem2;
int main(void){
    pthread_t tid1,tid2;
    int i=0;

    sem_init(&sem1,0,1);
    sem_init(&sem2,0,0);
    for(i=0;i<2;i++){
        pthread_create(&tid1,NULL,funA,NULL);
        pthread_create(&tid2,NULL,funB,NULL);
        pthread_join(tid1,NULL);
        pthread_join(tid2,NULL);
    }
    printf("\n");
    sem_destroy(&sem1);
    sem_destroy(&sem2);
    return 0;
}

void* funA(void* arg){
    sem_wait(&sem1);
    printf("1\t");
    sem_post(&sem2);
    return NULL;
}

void* funB(void* arg){
    sem_wait(&sem2);
    printf("2\t");
    sem_post(&sem1);
    return NULL;
}

五、实验步骤

步骤1. 编辑源代码test7.c

源代码test7.c内容见上述参考代码。

mkdir test7
cd test7
vim test7.c

在这里插入图片描述

步骤2. 编译源代码test7.c

gcc test7.c -o test7 -g -pthread

在这里插入图片描述

步骤3. 运行可执行程序test7

./test7

在这里插入图片描述

步骤4. 进一步调试源代码test7.c

实现以上的Linux的C程序,并做如下改动:

(1)在funA内,把原来输出的“1”改成输出自己的学号。

void* funA(void* arg){
    sem_wait(&sem1);
    printf("123456789\t");
    sem_post(&sem2);
    return NULL;
}

(2)在funB内,把原来输出的“2”改成输出自己的姓名。

void* funB(void* arg){
    sem_wait(&sem2);
    printf("zhc\n");
    sem_post(&sem1);
    return NULL;
}

(3)将main函数的for循环次数改为5次。

(4)在main函数的第一个pthread_join前边,输出“我是主线程,子线程已启动完毕,我将阻塞自己\n”。

(5)在main函数的第二个pthread_join后边,输出“我是主线程,子线程都已结束,我将继续运行\n”。

for(i=0;i<5;i++){
    pthread_create(&tid1,NULL,funA,NULL);
    pthread_create(&tid2,NULL,funB,NULL);
    printf("我是主线程,子线程已启动完毕,我将阻塞自己\n");
    pthread_join(tid1,NULL);
    pthread_join(tid2,NULL);
    printf("我是主线程,子线程都已结束,我将继续运行\n");
}

重新进行编译运行:

在这里插入图片描述

六、实验结果

完整代码如下:

#include<semaphore.h>
#include<pthread.h>
#include<stdio.h>
#include<stdlib.h>

void* funA(void*);
void* funB(void*);

sem_t sem1,sem2;
int main(void){
    pthread_t tid1,tid2;
    int i=0;

    sem_init(&sem1,0,1);
    sem_init(&sem2,0,0);
    for(i=0;i<5;i++){
        pthread_create(&tid1,NULL,funA,NULL);
        pthread_create(&tid2,NULL,funB,NULL);
        printf("我是主线程,子线程已启动完毕,我将阻塞自己\n");
        pthread_join(tid1,NULL);
        pthread_join(tid2,NULL);
        printf("我是主线程,子线程都已结束,我将继续运行\n");
    }
    printf("\n");
    sem_destroy(&sem1);
    sem_destroy(&sem2);
    return 0;
}

void* funA(void* arg){
    sem_wait(&sem1);
    printf("123456789\t");
    sem_post(&sem2);
    return NULL;
}

void* funB(void* arg){
    sem_wait(&sem2);
    printf("zhc\n");
    sem_post(&sem1);
    return NULL;
}

运行结果如下:

在这里插入图片描述

七、实验总结

  这个实验主要是使用 POSIX 线程和信号量来实现线程间的同步输出,让两个线程交替向终端打印字符 “1” 和 “2”。在这个实验中,我学到了如何使用信号量来控制线程的执行顺序,以及如何使用 POSIX 线程库来创建和管理线程。
  首先,我对信号量有了更深入的了解。在这个实验中,我使用了两个信号量sem1sem2,分别用于控制两个线程的执行顺序。通过sem_waitsem_post函数来操作信号量,我成功地实现了线程间的同步输出。这让我对信号量的作用有了更清晰的认识,它可以有效地管理和控制线程的执行顺序,避免出现竞争条件和资源冲突。
  其次,我对 POSIX 线程库有了更深入的了解。通过使用pthread_createpthread_join函数,我成功地创建了两个线程并等待它们的结束。我意识到线程的创建和管理是需要仔细考虑的,特别是在涉及到线程间的通信和同步时,需要确保线程的执行顺序是可控的和可预测的。
  在整个实验过程中,我遇到了一些问题,比如最初的编译错误,但通过查找资料和尝试不同的方法,我最终成功地解决了这些问题。这让我明白了在编程过程中遇到困难时要保持耐心,并且善用搜索引擎和查阅相关文档,这对于解决问题非常重要。
  总的来说,这个实验让我对信号量和 POSIX 线程有了更深入的理解,我学会了如何使用它们来实现线程间的同步和协作。同时,我也体会到了在编程实践中遇到问题时要有耐心和勇于尝试新的方法的重要性。这将对我的日后的编程工作和学习都大有裨益。

相关推荐

  1. CPP线管理实现

    2024-06-07 13:46:01       35 阅读
  2. linux 线笔记

    2024-06-07 13:46:01       52 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-06-07 13:46:01       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-06-07 13:46:01       106 阅读
  3. 在Django里面运行非项目文件

    2024-06-07 13:46:01       87 阅读
  4. Python语言-面向对象

    2024-06-07 13:46:01       96 阅读

热门阅读

  1. vue开发网站--刷新当前页面

    2024-06-07 13:46:01       34 阅读
  2. C++开源项目

    2024-06-07 13:46:01       29 阅读
  3. UE4动作游戏实例RPG Action解析-导语

    2024-06-07 13:46:01       32 阅读
  4. Android 跳转系统Settings各界面的ACTION及示例

    2024-06-07 13:46:01       32 阅读
  5. 【chatgpt】学术翻译和英文润色prompt

    2024-06-07 13:46:01       34 阅读
  6. NLP--词袋模型

    2024-06-07 13:46:01       28 阅读
  7. 【力扣】合并k个升序链表

    2024-06-07 13:46:01       29 阅读
  8. python-NLP常用数据集0.1.012

    2024-06-07 13:46:01       34 阅读
  9. 知识蒸馏——讨论区

    2024-06-07 13:46:01       31 阅读
  10. stm32 h5 串口采用DMA循环BUFF接收数据

    2024-06-07 13:46:01       25 阅读
  11. 用 Sentence Transformers v3 训练和微调嵌入模型

    2024-06-07 13:46:01       24 阅读
  12. 解决跨域问题

    2024-06-07 13:46:01       29 阅读
  13. 供应链管理是什么?能解决什么问题?

    2024-06-07 13:46:01       28 阅读
  14. 分布式防止重复请求或者高并发防止重复提交

    2024-06-07 13:46:01       21 阅读
  15. Flutter与iOS原生混合开发 iOS项目集成Flutter

    2024-06-07 13:46:01       36 阅读