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 线程有了更深入的理解,我学会了如何使用它们来实现线程间的同步和协作。同时,我也体会到了在编程实践中遇到问题时要有耐心和勇于尝试新的方法的重要性。这将对我的日后的编程工作和学习都大有裨益。

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Francek Chen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值