POSIX线程编程

news2024/12/26 16:50:11

死在山野的风里,活在自由的梦里
本专栏参考教材是四川轻化工大学陈年老师的linux实验指导手册(含学习通的一些程序笔记)。

POSIX线程编程

    • 1.线程是什么
    • 2.创建线程
      • 创建一个用户级的线程,实现在线程中更改进程(主线程)中的数据并输出验证修改结果。26-2.c
      • 利用多线程实现单词统计,即通过命令行参数指定多个文件给程序统计其中的单词数,程序采用为每一个文件创建一个线程来统计其单词数。

1.线程是什么

是一个程序内可被操作系统调用的,可以并发运行的任务

用于同时监控一个程序里面的多个并发的任务

(如果用父子进程也能同时监控,但是是用不同进程去监控的)

切换时开销更小

2.创建线程

创建一个用户级的线程,实现在线程中更改进程(主线程)中的数据并输出验证修改结果。26-2.c

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

static int i = 1;
//i是全局变量

void *create(void *arg)	
{	//函数名前加*,说明返回的是一个指向函数的指针
   printf("new pthread ...\n");
   printf("shared data = %d\n",i);
   printf("my tid is %ld\n",(unsigned long int)pthread_self());
   //在线程中通过pthread_self()函数返回自己的pid,类型为无符号长整数(unsigned long int),在printf中用%ld格式化输出。
   i=2;
   //修改全局变量i的值
   return (void *)0;
}

int main()
{
   pthread_t l;
   //l用来存储线程的tid,数据类型pthread_t是无符号长整数(unsigned long int)
   i=3;
   //修改全局变量i的值	
   if(pthread_create(&l,NULL,create,NULL))
   {	//pthread_create()函数需要四个参数,其中第一个是存线程tid的地址&l,并且会向l返回所创建线程的tid,第三个变量是线程程序的起始地址,即指向线程程序的指针
   	//pthread_create()函数成功则返回0,否则返回出错编号
   	printf("create pthread failed\n");
   	return -1;
   }
   else
   {
   	sleep(1);
   	printf("create pthread successfully\n");
   	printf("And shared data = %d\n return tid = %ld\n",i,(unsigned long int)l);
   	//输出main中i的值以及pthread_create()函数所创建线程的ID——l的值
   	return 0;
   }
   int n = sizeof(pthread_t);
   printf("the pthread_t has %d Byte\n",n);

}

在这里插入图片描述
完成利用多线程实现单词统计的实验(参考教科书P264例子)。

利用多线程实现单词统计,即通过命令行参数指定多个文件给程序统计其中的单词数,程序采用为每一个文件创建一个线程来统计其单词数。

提示:可以包含ctype.h文件,利用isalnum(int c)函数判断字符变量c是否为数字或字母,是则返回真(非零)。

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <stdbool.h>
#include <string.h>
#include <ctype.h>

int aaa(char filename[256])
{
    char ch;
    int wordStart = 0, sum = 0; // sum单词总数
    int i = 0, j = 0;
    char copy[20] = ""; //暂存读取的一个完整单词
    FILE *fp = NULL;

    fp = fopen(filename, "r");
    if (fp == NULL)
    {
        printf("文件打开出错了!");
        exit(0);
    }
    //读取文件内容
    while (!feof(fp))
    {
        ch = fgetc(fp);
        if (isalpha(ch)) //单词开始
        {
            wordStart = 1;  //标记
            copy[i++] = ch; //把一个完整单词每个字符依次存进copy
        }
        else if (!isalpha(ch) && wordStart == 1) //判断一个单词结束
        {
            sum++; //单词总个数+1
            //必须要这两个,不然会把别的字符也当成单词
            wordStart = 0;     
            i = 0;
            
            for (j = 0; j < 20; j++) //一个单词结束,copy清空
            {
                fflush(stdout);
            }
        }
    }
    printf("%s 总单词数为 %d \n", filename, sum);
    return sum;
}

int count[30] = {0};       //文件单词数初始值都是0
pthread_mutex_t fileMutex; //定义一个互斥变量
int main(int argc, char **argv)
{
    int i = 0;
    int flag; //如果输入命令格式不正确,应该给出提示
    if (argc < 2)
    {
        printf("./xx 1.txt 2.txt");
        exit(0);
    }
    *argv++; // +1
    pthread_t thread[argc - 1];

    /*互斥锁初始化*/
    flag = pthread_mutex_init(&fileMutex, NULL);
    if (flag != 0)
    {
        perror("出错了\n");
        return 1;
    }
    for (i = 0; i < argc - 1; i++)
    {
        flag = pthread_create(&thread[i], NULL, (void *)aaa, *argv++);
        if (flag != 0)
            return 1;
    }
    for (i = 0; i < argc - 1; i++)
        pthread_join(thread[i], (void **)&count[i]);

    int sum = 0;
    for (i = 0; i < 30; i++)
        sum += count[i];
    printf("总单词数量 %d", sum);
    return 0;
}

在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/779174.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Bean小结

Bean是Spring框架中最核心的两个概念之一&#xff08;另一个是面向切面编程AOP&#xff09;。 Bean 定义 Spring 官方文档对 bean 的解释是&#xff1a; In Spring, the objects that form the backbone of your application and that are managed by the Spring IoC contain…

从Vue2到Vue3【三】——Composition API(第三章)

系列文章目录 内容链接从Vue2到Vue3【零】Vue3简介从Vue2到Vue3【一】Composition API&#xff08;第一章&#xff09;从Vue2到Vue3【二】Composition API&#xff08;第二章&#xff09;从Vue2到Vue3【三】Composition API&#xff08;第三章&#xff09;从Vue2到Vue3【四】C…

webrtc QOS方法二.4(flexfec 实现可优化点)

一、冗余报文和媒体报文组织结构优化点 以单帧10个媒体报文&#xff0c;冗余度20%为例。这里webrtc输出要有10个媒体包2个冗余包。webrtc输出的报文序列如下&#xff1a; 代码实现如下&#xff1a; UlpfecGenerator::AddPacketAndGenerateFec&#xff1a;攒够足够的帧 Forwar…

使用springboot进行后端开发100问

properties和yaml文件怎么互转 安装插件 properties文件和yaml文件区别 properties 文件通过“.”和“”赋值&#xff0c;值前不加空格&#xff0c;yaml通过“:”赋值&#xff0c;值前面加一个空格&#xff1b;yaml文件缩进用空格&#xff1b; properties只支持键值对&#x…

C++实现LRU(逐句讲解)

使用双向链表解决此问题&#xff0c;因为双向链表可以很容易的获取到头结点和尾结点。题目要求 get 和 put 要在O(1)的时间复杂度下运行&#xff0c;很显然要用set或map。根据题意&#xff0c;应使用map。 unordered_map<int,Node*> cache; map->first为Node中的key&a…

查看RabbitMQ日志---trace插件的使用

我的RabbitMQ是安装在docker里面的 所以我以下的方法都是根据这个路径去操作的 如果RabbitMQ安装在其他地方 请自行百度 1. 显示正在运行的RabbitMQ容器的名称或ID&#xff1a; docker ps这将启动所有正在运行的 Docker 容器&#xff0c;并包含 RabbitMQ 容器的信息。 使用…

【Docker】Docker的数据管理

目录 一、Docker 的数据管理1.1数据卷1.2 数据卷容器1.3端口映射1.4容器互联&#xff08;使用centos镜像&#xff09; 二、Docker镜像的创建2.1基于现有镜像创建2.2&#xff0e;基于本地模板创建2.3 基于Dockerfile 创建联合文件系统&#xff08;UnionFS&#xff09;镜像加载原…

【云原生】Docker网络及Cgroup资源控制

一、Docker网络 1.docker网络实现原理 Docker使用Linux桥接&#xff0c;在宿主机虚拟一个Docker容器网桥(docker0)&#xff0c;Docker启动一个容器时会根据Docker网桥的网段分配给容器一个IP地址&#xff0c;称为Container-IP&#xff0c;同时Docker网桥是每个容器的默认网关。…

【Linux网络】 网络套接字(二)socket编程_UDP网络程序

目录 socket 编程接口socket 常见的APIsockaddr结构 UDP网络程序简单例子服务端代码编写服务端创建套接字服务端绑定运行服务器测试启动服务端 客户端代码编写客户端创建套接字启动客户端本地测试INADDR_ANY服务端接收信息发回到客户端如何进行网络测试 socket 编程接口 socke…

【机器学习】吃瓜教程 | 西瓜书 + 南瓜书 (1)

文章目录 一、绪论1、什么是机器学习&#xff1f;2、基本术语3、假设空间4、归纳偏好5、发展历程 二、模型评估与选择A、一种训练集一种算法2.1 经验误差 与 过拟合2.2 评估方法a) 留出法b) 交叉验证法c) 自助法d) 调参与最终模型 2.3 性能度量a) 错误率与精度b) 查准率、查全率…

RT-Thread快速入门-内核移植

1RT-Thread快速入门-内核移植 RT-Thread 快速入门系列前面的文章介绍了内核相关的知识&#xff0c;以及内核提供的接口函数和如何使用。 本篇文章主要介绍如何将 RT-Thread 内核移植到某个硬件平台之上。移植分为两部分&#xff1a; CPU 架构移植 BSP 移植 也就是将 RT-Th…

MySQL第二课表的增删插改

&#x1f49b; 后端进行的表的操作增删查改 现在是建了一个成绩表&#xff0c;注意哈。 decimal(2,1). 2是M表示有两个有效数字长度&#xff0c;1是D的长度&#xff0c;即小数点后有一位(10分制) &#x1f493;开始 1.增加&#xff1a; insert into 表名 values(值&#xff0…

安装VS Code 和 MiKTeX开发环境

下载&#xff1a; Getting MiKTeX 然后以管理员方式运行安装。 配置VS Code 之后配置VS Code&#xff0c;选择扩展&#xff08;两个位置都可以&#xff09;&#xff0c;然后搜索Latex&#xff1a; 然后打开设置&#xff1a; 这样就打开了setting.json文件&#xff0c; 然后…

SQL注入之Oracle环境搭建

SQL注入之Oracle环境搭建 前言 Oracle Database&#xff0c;又名Oracle RDBMS&#xff0c;或简称Oracle。是甲骨文公司的一款关系数据库管理系统。它是在数据库领域一直处于领先地位的产品。可以说Oracle数据库系统是世界上流行的关系数据库管理系统&#xff0c;系统可移植性…

gitlab上传新项目全过程

gitlab上传新项目全过程 一、前期准备1.1 gitlab配置1.2 gitlab安装1.3 需要在gitlab上新建一个空项目 二、本地操作2.1 gitlab上传新项目全过程2.2 gitlab将远程项目拉取到本地全过程 三、常见问题及解决四、常用命令4.1 代码更新提交命令4.2 其他指令 一、前期准备 1.1 gitl…

less中引入自定义字体文件

前言 一般做后台管理系统UI没有影响要求可以不使用自定义字体。但是在大屏项目中&#xff0c;高度自定义化&#xff0c;就肯定需要UI导出字体文件&#xff0c;然后放到服务器上或者是我们项目文件中&#xff0c;我们前端引入后在页面中使用。 下面以放在项目文件中为例。 各…

【linux】五种IO模型与非阻塞IO

文章目录 一、IO的概念二、IO的五种模型2.1 概念2.2 对比五种IO 三、非阻塞IO3.1 fcntl文件描述符控制3.2 以非阻塞轮询方式读取标准输入 一、IO的概念 前面我们说过其实IO就是拷贝数据。 先说一下读取的接口&#xff1a; 当系统调用read/recv的时候会有两种情况 ①没有数据&a…

【C语言】指针进阶(3)

目录 指针和数组笔试题解析 一维数组 字符数组 二维数组 指针笔试题 在前面两篇文章&#xff0c;我们已经学完了指针进阶的所有知识点。在这篇文章中&#xff0c;我们主要学习的是一些常见的笔试题的总结。 指针和数组笔试题解析 在做题之前&#xff0c;我们先复习一下之…

第三讲:k8s核心概念和专业术语

序言&#xff1a;这里只对概念继续基础阐述&#xff0c;不做具体案例&#xff0c;这位博主写的特别详细&#xff0c;想要对k8s深入的了解可以跳转了&#xff0c;作为小白的我看的有点懵&#xff0c;毕竟没实践过 链接地址→ http://t.csdn.cn/ZYtEF 这篇文章写了将近两万字对各…

mybatis-plus 缓存深入实践(二)

mybatis-plus 缓存&#xff08;一&#xff09;回顾、缓存&#xff08;二&#xff09;深入实践