Linux期末复习——多线程编程

news2024/11/17 1:34:45

线程概述

        

线程基本编程

        函数说明 

pthread_create(): 创建线程,成功返回0
pthread_exit():  主动退出线程,成功返回0
pthread_join():  挂起线程等待结束,成功返回0
pthread_cancel在别的线程中终止另一个线程的执行,成功返回0

        示例代码:创建三个线程,每个线程重用同一个执行,每个线程五次循环,每次循环随机等待1-10s。

        

/* thread.c */

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

#define THREAD_NUMBER		3    /*宏定义线程数量*/
#define REPEAT_NUMBER		5    /*宏定义每个线程的任务数量*/
#define DELAY_TIME_LEVELS	10.0/*小任务之间的最大时间间隔*/

/*定义线程处理过程的函数*/
void * thrd_func(void *arg)
{
	int thrd_num = (int)arg;
	int delay_time = 0;
	int count = 0;
	
	printf("Thread %d is starting\n", thrd_num);

	/*循环每个线程调用这个线程处理函数的时候要进行五次任务,所以循环五次*/
	for (count = 0; count < REPEAT_NUMBER; count++)
	{		
		delay_time = (int)(rand() * DELAY_TIME_LEVELS/(RAND_MAX)) + 1;
		sleep(delay_time);
        /*线程几:工作 几 次 等待 几 秒*/
		printf("\tThread %d: job %d delay = %d\n", thrd_num, count, delay_time);
	}
	printf("Thread %d finished\n", thrd_num);/*五次任务做完要输出线程几完成了*/
	pthread_exit(NULL);
}

/*主函数*/
int main(void)
{

     /*结构体解释:
    typedef unsigned long int pthread_t;  
    用途:pthread_t用于声明线程ID。    
    sizeof(pthread_t) =4;*/

    /*先赋值工作数*/
	pthread_t thread[THREAD_NUMBER];
       

	int no = 0, res;
	void * thrd_ret;
	
	srand(time(NULL));
        /*
          time(NULL);就是返回从1970年元旦午夜0点到现在的秒数。 srand(time(NULL)); 是以当前时间为种子,产生随意数。

          srand和rand()配合使用产生伪随机数序列。
          rand函数在产生随机数前,需要系统提供的生成伪随机数序列的种子,rand根据这个种子的值产生一系列随机数。
          如果系统提供的种子没有变化,每次调用rand函数生成的伪随机数序列都是一样的。
          srand(unsigned seed)通过参数seed改变系统提供的种子值,从而可以使得每次调用rand函数生成的伪随机数序列不同,
          从而实现真正意义上的“随机”。通常可以利用系统时间来改变系统的种子值,
          即srand(time(NULL)),可以为rand函数提供不同的种子值,进而产生不同的随机数序列  
        */

	/*循环创建三个线程*/
	for (no = 0; no < THREAD_NUMBER; no++)
	{
		res = pthread_create(&thread[no], NULL, thrd_func, (void*)no);
                /*
                 &thread[no]:线程标识符,表示线程的标号;
                   NULL:线程属性,通常取NULL; 
                   thrd_func:线程处理函数;
                   (void*)no:传递给线程处理函数的参数;
                              函数成功执行返回0,出错返回错误码;
 
                  pthread_create()函数作用,创建一个线程,并指定线程处理函数thrd_func,从而执行该函数规定的动作;
                */
		if (res != 0)
		{
			printf("Create thread %d failed\n", no);/*pthread_create失败返回0*/
			exit(res);
		}
	}
	
	printf("Create threads success,Waiting for threads to running..\n");/*成功输出这句*/
	
    /*循环挂起线程*/
	for (no = 0; no < THREAD_NUMBER; no++)
	{
		res = pthread_join(thread[no], &thrd_ret); //&thrd_ret:用户定义的指针,用来存储被等待线程结束时返回值;
                /*pthread_join使一个线程等待另一个线程结束。                  
                  代码中如果没有pthread_join主线程会很快结束从而使整个进程结束,从而使创建的线程没有机会开始执行就结束了。
                  加入pthread_join后,主线程会一直等待直到等待的线程结束自己才结束,使创建的线程有机会执行。
                  该函数作用:当thread[no]尚未运行结束时,调用pthread_join()的主进程阻塞,直到thread[no]线程退出,该线程所占据的资源才被释放,主进程才能结束;
                  主进程等待线程运行结束后,pthread_join函数返回0,该线程资源释放;如果出错返回错误码;
           
                */
		if (!res)
		{
			printf("Thread %d joined\n", no);/*该语句打印出来代表thread[no]已经结束运行,释放其占据的资源*/
		}
		else
		{
			printf("Thread %d join failed\n", no);
		}
	}
	
	return 0;        
}

线程之间的同步互斥 

        信号量适用于同时可用的资源是多个

        互斥锁适用于同时可用的资源唯一

互斥锁线程控制

        

互斥锁基本函数
互斥锁初始化pthread_muttex_init
互斥锁上锁        pthread_muttex_lock
互斥锁判断上锁pthread_muttex_trylock()
互斥锁解锁pthread_muttex_unlock
消除互斥锁pthread_muttex_destroy

        示例代码(是在上一个示例基础上增加了互斥锁的功能):

        

/* thread_mutex.c */
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#define THREAD_NUMBER		3      /*有三个线程*/
#define REPEAT_NUMBER		3      /*每个线程三个任务*/
#define DELAY_TIME_LEVELS	10.0   /*每个线程任务随机等待1-10s*/
pthread_mutex_t mutex;

/**/
void * thrd_func(void *arg)
{
	int thrd_num = (int)arg;
	int delay_time = 0, count = 0;
	int res;
	
	res = pthread_mutex_lock(&mutex); /*上互斥锁,成功返回0,非0值代表失败,并返回出错信息;*/	
	if (res)
	{
        /*上锁失败*/
		printf("Thread %d lock failed\n", thrd_num);	
		pthread_exit(NULL);
	}
    /*上锁成功输出一句线程开始*/	
	printf("Thread %d is starting\n", thrd_num);
    /*三次任务*/
	for (count = 0; count < REPEAT_NUMBER; count++)
	{	
        delay_time = (int)(rand() * DELAY_TIME_LEVELS/(RAND_MAX)) + 1;
		sleep(delay_time);
	    printf("\tThread %d: job %d delay = %d\n", thrd_num, count, delay_time);
	}
    /*线程完成*/
	printf("Thread %d finished\n", thrd_num);
	/*主动停止线程*/	    
	pthread_exit(NULL);
}

int main(void)
{
    /*一些定义*/
	pthread_t thread[THREAD_NUMBER];
	int no = 0, res;
	void * thrd_ret;
	
	srand(time(NULL));
	
    /*互斥锁初始化*/
	pthread_mutex_init(&mutex, NULL);
    /*参数解释:
    &mutex创建互斥锁,都这么写
    NULL表示创建的是快速互斥锁,调用线程会阻塞直至拥有互斥锁的线程解锁为止,知道有这么回事就好            
    */
    
    /*循环创建三个线程*/
	for (no = 0; no < THREAD_NUMBER; no++)
	{
        /*线程号,默认NULL,线程处理函数,传递参数*/
		res = pthread_create(&thread[no], NULL, thrd_func, (void*)no);
		if (res != 0)
		{
			printf("Create thread %d failed\n", no);/*报错*/
			exit(res);
		}
	}
	
	printf("Create threads success\n Waiting for threads to finish...\n");/*创建成功,等待线程创建完毕*/

    /*做三次任务,每个线程挂起,防止退出太快*/
	for (no = 0; no < THREAD_NUMBER; no++)
	{
		res = pthread_join(thread[no], &thrd_ret);
		if (!res)
		{ 
            printf("Thread %d joined\n", no); 
        }
		else
		{  
            printf("Thread %d join failed\n", no); 
        }
		pthread_mutex_unlock(&mutex);/*解开互斥锁*/		
	}	
	pthread_mutex_destroy(&mutex);	/*消除(删除)互斥锁*/
	return 0;        
}

       信号量线程控制

        互斥锁是一种特殊的信号量,互斥锁初始值为1,信号量初始值为0

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

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

相关文章

sql文件批处理程序-java桌面应用

项目效果&#xff1a; 支持sql文件夹批处理&#xff0c;选中文件夹或者sql文件 支持测试连接&#xff0c;可以校验数据库配置 支持报错回显&#xff0c;弹出报错文件名以及问题语句 支持在程序中修改错误语句&#xff0c;用户可以选择保存修改内容继续执行或不保存修改只执行…

线性代数 第四章 线性方程组

一、矩阵形式 经过初等行变换化为阶梯形矩阵。当&#xff0c;有解&#xff1b;当&#xff0c;有非零解。 有解&#xff0c;等价于 可由线性表示 克拉默法则&#xff1a;非齐次线性方程组中&#xff0c;系数行列式&#xff0c;则方程组有唯一解&#xff0c;且唯一解为 其中是…

TestCenter测试管理工具

estCenter&#xff08;简称TC&#xff09;一款广受好评的测试管理工具&#xff0c;让测试工作更规范、更有效率&#xff0c;实现测试流程无纸化&#xff0c;测试数据资产化。 产品概述 TC流程图 产品功能 一、案例库 案例库集中化管理&#xff0c;支持对测试用例集中管理&…

Gartner报告 | Mendix再次成为低代码领导者!Mendix在愿景完整性和执行能力领域的排名最为靠前。

本文作者: Hans de Visser, Mendix 首席产品官 在最新发布的2023 Gartner魔力象限图™ 中对于企业级低代码应用程序平台&#xff0c;Gartner指出&#xff0c;企业IT领导者需要满足“应用程序开发向更高抽象级别迈进的步伐&#xff0c;并采用低代码平台来加速应用程序开发。” 此…

【华为】路由器以PPPoE拨号接入广域网

组网需求 用户希望以PPPoE拨号方式接入广域网&#xff0c;如图1所示&#xff0c;Router作为PPPoE客户端&#xff0c;得到PPPoE服务器的认证后获得IP地址&#xff0c;实现用户接入互联网的需求。内网网关地址&#xff08;即VLANIF1接口的IP地址&#xff09;为10.137.32.1/24。 …

N-131基于jsp,ssm物流快递管理系统

开发工具&#xff1a;eclipse&#xff0c;jdk1.8 服务器&#xff1a;tomcat7.0 数据库&#xff1a;mysql5.7 技术&#xff1a; springspringMVCmybaitsEasyUI 项目包括用户前台和管理后台两部分&#xff0c;功能介绍如下&#xff1a; 一、用户(前台)功能&#xff1a; 用…

UE5 Android下载zip文件并解压缩到指定位置

一、下载是使用市场的免费插件 二、解压缩是使用市场的免费插件 三、Android路径问题 windows平台下使用该插件没有问题&#xff0c;只是在Android平台下&#xff0c;只有使用绝对路径才能进行解压缩&#xff0c;所以如何获得Android下的绝对路径&#xff1f;增加C文件获得And…

生态扩展:Flink Doris Connector

生态扩展&#xff1a;Flink Doris Connector 官网地址&#xff1a; https://doris.apache.org/zh-CN/docs/dev/ecosystem/flink-doris-connector flink的安装&#xff1a; tar -zxvf flink-1.16.0-bin-scala_2.12.tgz mv flink-1.16.0-bin-scala_2.12.tgz /opt/flinkflink环境…

【c++|opencv】二、灰度变换和空间滤波---5.中值滤波

every blog every motto: You can do more than you think. https://blog.csdn.net/weixin_39190382?typeblog 0. 前言 1. 中值滤波 #include<iostream> #include<opencv2/opencv.hpp> #include"Salt.h"using namespace cv; using namespace std;voi…

NEFU离散数学实验4-数论

相关概念 离散数学中的数论相关概念和公式如下&#xff1a; 1.最大公约数(GCD)&#xff1a;两个整数a和b的最大公约数是能够同时整除a和b的最大正整数&#xff0c;记作GCD(a, b)。 2.最小公倍数(LCM)&#xff1a;两个整数a和b的最小公倍数是能够同时整除a和b的最小正整数&#…

MySQL-Galera-Cluster集群详细介绍

目录 一、什么是Mysql集群&#xff1f;1.单节点mysql存在的常见问题2.mysql集群介绍3.Mysql集群的优点和风险 二、Mysql集群的一些疑问1.mysql的AB复制和Galera Cluster有什么区别&#xff1f;2.什么情况下适用AB复制&#xff0c;什么情况下使用Galera cluster&#xff1f;3.可…

给出n个字母(a-z),找出出现次数最多的字母并输出。(附ASCII码表)

Result01&#xff1a; 两层for循环枚举&#xff0c;时间复杂度为O(N2)&#xff0c;空间复杂度O(1)。 //暴力解&#xff1a;public static char Result01(char[] chars) {int maxNums 0;//保存最大出现次数int index 0;//记录出现次数最多的元素在数组中的下标for (int i …

初识【Java类和对象】

目录 1.面向对象的初步认知 1.1什么是面向对象? 1.2面向对象与面向过程 2.类定义和使用 2.1简单认识类 2.2类的定义格式 3.类的实例化 3.1什么是实例化 3.2类和对象的说明 4.this引用 4.1为什么要有this的引用 4.2什么是this引用 4.3this引用的特性 &#x1…

3 — NLP 中的标记化:分解文本数据的艺术

一、说明 这是一个系列文章的第三篇文章&#xff0c; 文章前半部分分别是&#xff1a; 1 — NLP 的文本预处理技术2 — NLP中的词干提取和词形还原&#xff1a;文本预处理技术 在本文中&#xff0c;我们将介绍标记化主题。在开始之前&#xff0c;我建议您阅读我之前介绍…

【机器学习合集】模型设计之注意力机制动态网络 ->(个人学习记录笔记)

文章目录 注意力机制1. 注意力机制及其应用1.1 注意力机制的定义1.2 注意力机制的典型应用 2. 注意力模型设计2.1 空间注意力机制2.2 空间注意力模型2.3 通道注意力机制2.4 空间与通道注意力机制2.5 自注意力机制2.5 级联attention 动态网络1. 动态网络的定义2. 基于丢弃策略的…

高校教务系统登录页面JS分析——西安电子科技大学

高校教务系统密码加密逻辑及JS逆向 本文将介绍西安电子科技大学高校教务系统的密码加密逻辑以及使用JavaScript进行逆向分析的过程。通过本文&#xff0c;你将了解到密码加密的基本概念、常用加密算法以及如何通过逆向分析来破解密码。 &#x1f31f;PS&#xff1a;我还以为和…

Linux服务器使用GPU技巧

进行深度学习实验的时候用pytorch-gpu&#xff0c;经常要与GPU打交道&#xff1b; 所以经常遇到奇奇怪怪的问题&#xff1b; 查看GPU占用情况 watch -n 10 nvidia-smi 使用技巧 torch.nn.DataParallel() CLASStorch.nn.DataParallel(module, device_idsNone, output_devic…

部署Kubernetes(k8s)多主的高可用集群

文章目录 文档说明网络拓扑IP地址规划 安装步骤环境准备关闭防火墙关闭SELinux关闭Swap分区修改主机名称解析设置主机名称转发 IPv4 并让 iptables 看到桥接流量升级操作系统内核导入elrepo gpg key安装elrepo YUM源仓库安装kernel-lt版本设置grub2默认引导为0重新生成grub2引导…

关于CSS的几种字体悬浮的设置方法

关于CSS的几种字体悬浮的设置方法 1. 鼠标放上动态的2. 静态的&#xff08;位置看上悬浮&#xff09;2.1 参考QQ邮箱2.2 参考知乎 1. 鼠标放上动态的 效果如下&#xff1a; 代码如下&#xff1a; <!DOCTYPE html> <html lang"en"> <head><met…

使用复合机器人有哪些注意事项

随着科技的快速发展&#xff0c;复合机器人在各个领域得到了广泛应用。复合机器人可以完成多种任务&#xff0c;具备高效、精准、灵活等优势。然而&#xff0c;在使用复合机器人时&#xff0c;我们也需要注意一些事项&#xff0c;以确保安全和有效地使用这些机器人。 一、安装要…