main函数

Linux多线程编程初探

南笙酒味 提交于 2020-02-24 14:37:20
Linux线程介绍 进程与线程   典型的UNIX/Linux进程可以看成只有一个控制线程:一个进程在同一时刻只做一件事情。有了多个控制线程后,在程序设计时可以把进程设计成在同一时刻做不止一件事,每个线程各自处理独立的任务。     进程是程序执行时的一个实例,是担当分配系统资源(CPU时间、内存等)的基本单位。在面向线程设计的系统中,进程本身不是基本运行单位,而是线程的容器。程序本身只是指令、数据及其组织形式的描述,进程才是程序(那些指令和数据)的真正运行实例。   线程 是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。线程包含了表示进程内执行环境必须的信息,其中包括进程中表示线程的线程ID、一组寄存器值、栈、调度优先级和策略、信号屏蔽字、errno常量以及线程私有数据。进程的所有信息对该进程的所有线程都是共享的,包括可执行的程序文本、程序的全局内存和堆内存、栈以及文件描述符。在Unix和类Unix操作系统中线程也被称为轻量级进程(lightweight processes),但轻量级进程更多指的是内核线程(kernel thread),而把用户线程(user thread)称为线程。 "进程——资源分配的最小单位,线程——程序执行的最小单位"  

动态库的soname实验

一个人想着一个人 提交于 2020-02-23 13:31:02
soname的实验演示: 1、制作一个动态库,源文件b.c,程序如下: #include <stdio.h> int funb(int a, int b) { printf("hello funb\n"); return a + b; } 2、编译成动态库 gcc -fPIC -shared -Wl,-soname,libfuncb.so -o libfuncb.so.1 b.c 注意生成的文件的真实名字是libfuncb.so.1, 而这个动态库的soname是libfuncb.so。 root@vm:/home/zhangmeng/sonametest# gcc -fPIC -shared -Wl,-soname,libfuncb.so -o libfuncb.so.1 b.c root@vm:/home/zhangmeng/sonametest# ll total 24 drwxr-xr-x 2 root root 4096 Feb 23 11:54 ./ drwxrwxrwx 56 zhangmeng zhangmeng 4096 Feb 23 11:44 ../ -rw-r--r-- 1 root root 87 Feb 23 11:45 b.c -rwxr-xr-x 1 root root 8112 Feb 23 11:54 libfuncb.so.1* -rw-r-

Go 系列教程 ——第 29 篇:Defer

自作多情 提交于 2020-02-22 19:45:13
什么是 defer? defer 语句的用途是:含有 defer 语句的函数,会在该函数将要返回之前,调用另一个函数。这个定义可能看起来很复杂,我们通过一个示例就很容易明白了。 示例 package main import ( "fmt" ) func finished() { fmt.Println("Finished finding largest") } func largest(nums []int) { defer finished() fmt.Println("Started finding largest") max := nums[0] for _, v := range nums { if v > max { max = v }} fmt.Println("Largest number in", nums, "is", max) } func main() { nums := []int{78, 109, 2, 563, 300} largest(nums) } 上面定义了接口 Interface ,它包含了两个方法: calculate() 计算并返回项目的收入,而 source() 返回项目名称。 在 playground 上运行 上面的程序很简单,就是找出一个给定切片的最大值。 largest 函数接收一个 int 类型的切片作为参数

Python高级编程-多进程

戏子无情 提交于 2020-02-22 15:09:58
要让Python程序实现多进程(multiprocessing),我们先了解操作系统的相关知识。 Unix/Linux操作系统提供了一个 fork() 系统调用,它非常特殊。普通的函数调用,调用一次,返回一次,但是 fork() 调用一次,返回两次,因为操作系统自动把当前进程(称为父进程)复制了一份(称为子进程),然后,分别在父进程和子进程内返回。 子进程永远返回 0 ,而父进程返回子进程的ID 。这样做的理由是,一个父进程可以fork出很多子进程,所以,父进程要记下每个子进程的ID,而子进程只需要调用 getppid() 就可以拿到父进程的ID。 Python的 os 模块封装了常见的系统调用,其中就包括 fork ,可以在Python程序中轻松创建子进程: 1 # /usr/bin/python 2 import os 3 import time 4 5 6 def main(): 7 pid = os.fork() 8 if pid == 0: # 子进程中返回0 9 print("I am child process %d, my parent is %d" % (os.getpid(), os.getppid())) 10 time.sleep(1) 11 else: # 父进程中返回子进程id 12 print("I %d just created child %d"

PTA练习Day02

馋奶兔 提交于 2020-02-22 13:54:53
PTA练习Day02 练习2-14 求奇数分之一序列前N项和 (15分) 练习2-15 求简单交错序列前N项和 (15分) 练习2-17 生成3的乘方表 (15分) 练习2-18 求组合数 (15分) 习题2-1 求整数均值 (10分) 习题2-2 阶梯电价 (15分) 习题2-3 求平方与倒数序列的部分和 (15分) 习题2-4 求交错序列前N项和 (15分) 习题2-5 求平方根序列前N项和 (15分) 习题2-6 求阶乘序列前N项和 (15分) 练习2-14 求奇数分之一序列前N项和 (15分) 本题要求编写程序,计算序列 1 + 1/3 + 1/5 + … 的前N项之和。 输入格式: 输入在一行中给出一个正整数N。 输出格式: 在一行中按照“sum = S”的格式输出部分和的值S,精确到小数点后6位。题目保证计算结果不超过双精度范围。 输入样例 : 23 输出样例 : sum = 2.549541 # include <stdio.h> int main ( ) { int n , i , j = 1 ; double sum = 0 ; scanf ( "%d" , & n ) ; for ( i = 1 ; i <= n ; i ++ , j + = 2 ) { sum + = 1.0 / j ; } printf ( "sum = %lf" , sum ) ;

模块和包

只谈情不闲聊 提交于 2020-02-22 05:17:06
1. 模块和包 容器: 列表、元组、字符串、字典等,对数据的封装 函数: 对语句的封装 类: 对方法和属性的封装,即对函数和数据的封装 而模块(module)就是个程序,一个 .py 文件,模块分为三类: Python 标准库: 如 time、random 等 第三方模块: 如 requests、beautiful 等 应用程序自定义模块: 用户自定义模块 随机程序代码越写越多,每个文件里面的代码越来越长,越来越不容易维护。使用模块的好处: 模块化代码: 将不同功能的代码归类,提高代码的可维护性 避免重复造轮子: 编写代码可以不必从零开始,可以引用别人已经写好的模块,Python 有很多优秀的第三方模块 命名空间: 每个模块单独维护一个命名空间,不同模块相同函数名、变量名不会有冲突 Tips: 自定义模块的时候,不要与内置的模块名有冲突,不然会影响内置模块 1.1 包 为了避免不同的人编写的模块名相同,Python 引入了按目录来组织模块的方法 —— 包(Package) 不同包下的模块,名字相同不会有冲突,只要顶层的包名不冲突就行。 如何创建一个包: 创建一个文件夹,里面存放相应模块文件,文件夹名字即为包名 在文件夹中创建一个 __init__.py 文件,可以为空 1.2 导入模块 导入模块的几种常用方法: >>> import 模块1, 模块2... # sys.path

c语言进阶6-指针

我与影子孤独终老i 提交于 2020-02-22 02:43:27
指针是c语言的一个重要组成部分 是c语言的核心、精髓所在,用好指针可以在c语言编程中起到事半功倍的效果。一方面,可以提高程序的编译效率和执行速度以及实现动态的存储分配;另一方面,使用指针可使程序更灵活,全球表示各种数据结构,编写高质量的程序。 指针是c语言显著的优点之一,其使用起来十分灵活而且能提高某些程序的效率,但是如果使用不当则很容易造成系统错误。许多程序“挂死“往往都是由于错误地使用指针造成的 一、 地址与指针 系统的内存就好比是带有编号的小房间,如果想使用内存就需要得到房间编号。图1定义了一个整型变量i,整型变量需要4个字节,所以编译器为变量i分配的编号为1000~1003. 什么是地址? 地址就是内存区中对每个字节的编号 ,如图1所示的1000/1001/1002和1003就是地址,为了进一步说明来看图2. 内存地址 内容 1000 0 变量i 1004 1 变量j 1008 2 1012 3 1016 4 1020 5 图2所示的1000、1004等就是内存单元的地址,而0、1就是内存单元的内容,换种说法就是基本整型变量i在内存中的地址从1000开始。因为基本整型占4个字节,所以变量j在内存中的起始地址为1004,变量i的内容是0. 那么指针又是什么呢?这里仅将 指针看作是内存中的一个地址,多数情况下,这个地址就是内存中另一个变量的位置,如图3所示。

实战分析一个运行起来会卡死的Go程序

时光怂恿深爱的人放手 提交于 2020-02-21 08:20:27
序言 最近一位非常热心的网友建议结合demo来分析一下goroutine的调度器,而且还提供了一个demo代码,于是便有了本文,在此对这位网友表示衷心的感谢! 这位网友提供的demo程序可能有的gopher以前见过,已经知道了具体原因,但本文假定我们是第一次遇到这种问题,然后从零开始,通过一步一步的分析和定位,最终找到问题的根源及解决方案。 虽然本文不需要太多的背景知识,但最好使用过gdb或delve调试工具,了解汇编语言及函数调用栈当然就更好了。 本文我们需要重点了解下面这3个内容。 调试工具无法准确显示函数调用栈时如何找到函数调用链; 发生GC时,如何STOP THE WORLD; 什么时候抢占调度不会起作用以及如何规避。 本文的实验环境为AMD64 Linux + go1.12 Demo程序及运行现象 package main import( "fmt" "runtime" "time" ) func deadloop() { for { } } func worker() { for { fmt.Println("worker is running") time.Sleep(time.Second * 1) } } func main() { fmt.Printf("There are %d cores.\n", runtime.NumCPU()) goworker()

Rust笔记

假装没事ソ 提交于 2020-02-19 11:48:02
Rust笔记 文章目录 Rust笔记 Rust基本概念 Rust 数据类型 标量类型 复合类型 Rust函数 函数定义 函数参数 函数体 语句与表达式 函数返回值 控制流 if表达式 使用 else if 实现多重条件 在 let 语句中使用 if Rust基本概念 在rust中变量默认是不可变的,如果需要定义可变变量需要使用关键字 mut 进行声明 fn main() { let a = 10; //a变量是一个不可变变量 let mut b = 10; //b变量是一个可变变量 println!("{}",b); println!("{}", a); } 禁止试改不可变变量的值 let a = 10; a = 45; //error :试图修改不可变变量的值 常量 常量类似于不可变变量,但是不可变变量可以通过使用 mut 关键字使变量可变,而常量永远不可变并且不可使用 mut 关键字修饰常量。 const MAX_INT:i32 = 100; println!("{}", MAX_INT); 变量隐藏 我们可以定义一个与之前变量重名的新变量, 而新变量会 隐藏 之前的变量。 Rustacean 们称之为第一个变量被第二个 隐藏 了, 这意味着使用这个变量时会看到第二个值。 可以用相同变量名称来隐藏它自己, 以及重复使用 let 关键字来多次隐藏 fn main(){ let a

Go语言学习(二)-----Hello,World

拥有回忆 提交于 2020-02-19 10:17:40
用Eclipse+Goclipse写go代码的时候,感觉有点卡,尤其是在敲完一个“.”的时候,不知道大家都木有类似的经历。 暂且就用记事本好了,反正初级阶段,接触的代码都不多。 用记事本的话,会涉及到一些命令,可以查阅go语言的command资料: http://golang.org/cmd/go/ 看到有个朋友推荐基于IntelliJ改造的go-ide,貌似不错,等有时间在下载下来试试。 下面继续Go语言的学习。 一、Go程序的代码结构 以前一章节的hello word为例: package main import ( "fmt" ) func main() { fmt.Println("Hello world!") } 1.首先是包名,没啥说的 2.然后是导入,这里导入了fmt包,在main中用到了fmt包中的Println方法。导入的包也可以设置别名的,例如: package main import a "fmt" func main(){ a.Println("import alias test!"); } 这个例子中将fmt包设置了别名a。在后面使用的时候就直接写a来代替fmt。 3.接下来是函数, 函数的声明使用关键字func。整个程序将会从为main包中的main 函数开始执行,也就是所谓的入口函数。 4.需要说明的是:每一行语句结束之后,不需要写分号。 for循环中