linux有没有像C语音里<linux环境c程序设计计语言>这样的书

当前位置:
linux嵌入式程序设计师
公司:某高新技术企业股份公司
地点:北京地理位置
行业:仪器仪表·工业自动化
经验: 5年以上
性质:民营公司
规模:501-1000 职员
月薪:¥元
岗位职责:工作职责描述: &!--[if !supportLists]--&1、 &!--[endif]--&负责linux系统下程序模块的开发设计工作 &!--[if !supportLists]--&2、 &!--[endif]--&撰写相关技术文档 任职资格要求: &!--[if !supportLists]--&1、 &!--[endif]--&精通C/C++语言,熟悉linux嵌入式操作系统, 熟悉linux应用程序设计; &!--[if !supportLists]--&2、 &!--[endif]--&具备一定的软件工程知识,掌握基本软件开发流程和开发工具; &!--[if !supportLists]--&3、 &!--[endif]--&有网络管理软件、QT应用程序或linux驱动程序开发经验者优先考虑; &!--[if !supportLists]--&4、 &!--[endif]--&具有给予ARM平台嵌入式系统设计经验; &!--[if !supportLists]--&5、 &!--[endif]--&很好的团队协作精神; &!--[if !supportLists]--&6、 &!--[endif]--&本科以上学历,5年以上工作经验。任职资格的具体描述:工作职责描述: &!--[if !supportLists]--&1、 &!--[endif]--&负责linux系统下程序模块的开发设计工作 &!--[if !supportLists]--&2、 &!--[endif]--&撰写相关技术文档 任职资格要求: &!--[if !supportLists]--&1、 &!--[endif]--&精通C/C++语言,熟悉linux嵌入式操作系统, 熟悉linux应用程序设计; &!--[if !supportLists]--&2、 &!--[endif]--&具备一定的软件工程知识,掌握基本软件开发流程和开发工具; &!--[if !supportLists]--&3、 &!--[endif]--&有网络管理软件、QT应用程序或linux驱动程序开发经验者优先考虑; &!--[if !supportLists]--&4、 &!--[endif]--&具有给予ARM平台嵌入式系统设计经验; &!--[if !supportLists]--&5、 &!--[endif]--&很好的团队协作精神; &!--[if !supportLists]--&6、 &!--[endif]--&本科以上学历,5年以上工作经验。
企业介绍:是政府认定的国家级高新技术企业,旗下有3家全资子公司和两家控股子公司。主打产品为电动伸缩门、IC卡智能停车场管理系统、智能悬浮门、道闸、岗亭、旗杆、围栏、交通护栏等21大系列100余种具有自主知识产权的高科技产品,拥有130多项国家专利和国外专利。 公司在全国有60多家经销商、直属经营部和300多个业务驻点,销售和售后服务网络覆盖全国100%的直辖市、省会城市和地级市,并辐射到美国、沙特、印尼、马来西亚、新加坡、韩国、越南、台湾等十多个国家和地区。 产品畅销海内外。电动伸缩门以出众的品质、卓越的性能和优美的外观受到广大消费者追捧,成为党政机关、企事业单位、部队、学校、体育场馆、高档住宅区的首选产品,北京人民大会堂、国家博物馆、最高人民检察院、国家发改委、国务院新闻办、国家教育部、国家科技部、北京奥运会组委会和主场馆、北京军区司令部、上海世博会中国馆、上海复旦大学等国家机关、院校、纪念场馆都是红门的客户。 秉承“质量筑品牌,服务创未来”的经营理念,公司为打造世界名牌而做出了不懈的努力,深受政府机关、主流媒体、社会公众和广大消费者好评。 2008年,公司荣获“深圳市十大书香企业”、“深圳市劳动关系和谐企业”、“深圳市工伤预防先进单位”、“龙岗区知识产权优势企业”等荣誉称号;品牌荣获“深圳知名品牌”称号。 2009年,公司通过“国家高新技术企业”认定,并且荣获“广东省创争活动优秀单位”、“广东省无偿献血促进奖”、“深圳市工人先锋号”等荣誉称号;红门电动伸缩门、智能停车场收费系统和悬浮门三类产品同时获得“采用国际标准或国外先进标准产品证书”;电动伸缩门荣获“深圳市重点自主创新产品”认定;电动伸缩门、道闸系列产品获得欧盟CE强制认证。 2010年,公司通过ISO国际质量管理体系认证(换版)、SA国际社会责任管理体系认证和ISO1国际环境管理体系认证,并且荣获和“深圳市人民调解工作先进集体”称号;红门电动伸缩门、停车场管理系统和悬浮门三类产品同时荣获“深圳市自主创新产品”认定;电动伸缩门荣获“广东省名牌产品”称号。 2011年,公司通过OHSAS18001国际职业健康安全管理体系认证和“AAAA级标准化良好行为企业”认定,荣获“深圳市无偿献血先进集体”和“龙岗区自主创新20强企业”荣誉称号,并且取得平移门和道闸两类产品行业标准主编资格;品牌获得首届“中国门业十大品牌自动门类金奖”荣誉。 2012年,公司获得“深圳市和谐劳动关系先进企业”和“龙岗区2011年度创新与成长奖”荣誉;IC卡读写器通过中国国家强制性产品认证(3C);空降门、旗杆和道闸三类产品同时获得“采用国际标准或国外先进标准产品证书”。
*提醒:用人单位招聘人才,以任何名义向应聘者收取费用都属于违法行为。请应聘者提高警惕,切勿上当受骗。
可能感兴趣的职位
北京中视中科光电...
工作地点:北京 北京-海淀区
岗位工资:面议
北京凌天世纪自动...
工作地点:北京-通州区
岗位工资:元
北京森根科技有限...
工作地点:北京
岗位工资:面议
北京鑫禾丰医疗技...
工作地点:北京-石景山区
岗位工资:面议
北京红源光电技术...
工作地点:北京-朝阳区
岗位工资:面议
北京华辰康健科技...
工作地点:北京
岗位工资:面议
适合你的急招职位
相关职能搜索
相关地区搜索Linux软件工程师(C语言)实用教程 _正版电子书在线阅读_百度阅读
Linux软件工程师(C语言)实用教程
支持以下平台(点击下载客户端)
畅销飙升榜
Linux软件工程师(C语言)实用教程
亚马逊评分:
您也可能感兴趣
  本书主要内容包括:IJnux环境下C语言程序的设计过程,C语言编译器gcc、调试器gdb、工程管理器make的使用,多文件系统、文件操作、标准I/O库、串行通信程序的实现,进程的产生与控制、进程间的通信、Linux的图形编程、网络编程、数据库编程以及游戏程序的开发方法。
 本书结构合理、概念清楚、由浅入深、实用性强,是一本技能型的教材,适合Linux环境下软件工程技术人员使用,也可以作为软件、计算机等专业本、专科学生的教材。本书是开放源代码高校推进联盟“Linux软件工程师职业技能(C语言)资格”认证考试指定用书。
亚马逊评分
帮助平台入驻编程入门应从什么软件开始学_百度知道
编程入门应从什么软件开始学
现在有什么出名的编程软件。我是初三学生,就从哪一个开始学好?
提问者采纳
自己的编程语言;编程高手箴言&&lt!~,发现自己还是站在了原点,太急于求成,只要你自学完了高三数学.
程序=算法+数据结构+良好的编程风格第三步,努力入门了,苦练了很久的九阳神功..入门的不二选择.因为我相信.有多少人愿意静下心来学习的,数据库等慢慢学习吧:要有超乎常人的决心第三条;&gt,编程高手的利器:
数据结构(C语言版),数据结构学习方法和C语言一样;Linux内核 0;自己动手写操作系统&80x86汇编语言程序设计教程&gt,靠的是什么.有多少人愿意去学习内核的;&lt,看书想睡觉:
东南大学的操作系统
推荐书籍,计算机网络..这时候你可以挑一件 可视化开发工具 给自己使用吧,Asp,不必深入研究,你天才了;
&操作系统之哲学原理&gt.,一个编程高手的数学是很厉害的哦~.;&lt,有多少人沉迷在编程中的:
操作系统.等)TCP&#47,看视频,即使5年后,需要学习;&lt:
&lt,兄弟;&lt,我也希望中国拥有自己的PUC技术,中国人是世界上最聪明的人种.NET等)还要掌握独门暗器 Web开发的工具,学什么你都手到擒来.是因为我们太浮躁:
C语言程序设计;编译原理实现及实践&
&lt. ,又跳到了C#或者java等上面.学完了这些,看书:
&lt:要有坚强的意志力第二条.第五步;&&.;&lt?&汇编语言
王爽 第2版&gt,VB,其实你还是一只充满好奇的菜鸟而已.,像汇编啊,超过老师的教学.慢慢品味.&lt.把数学变为自己的利器;;九阳神功&
&lt:高等数学,初三就有这样的想法.
大概了解而已;欲速则不达&quot,你才有时间去学习这些数学),会有质的飞跃!你只要按照我的方法学习,你根本不用等到5年?没有.有了上面那些扎实的内功,自己的操作系统,我希望有生之年能看到;IP;
计算机组成原理,买适合自己的书;C语言实例解析精粹&gt.;&gt.当你回过头看时。我强烈支持你啊:
&lt.中国有句古话 &&&数据结构(C语言版),只学了个C语言,那我敢说,看上去平淡无奇;视频推荐;&lt,你只要有这个耐心就足够了.
视频推荐,离散数学,多上机编程. 你要每天上机编程;&!~我告诉你:
好书推荐,英语你好好学习哦~.很多人连基础都不会,太少了:不要以为你无所不能,我高二才开始的;&lt.当你对计算机深入了解以后! 其他的可以不用学习了,认为自己是个菜鸟,而不是软件工人.严蔚敏
大灰狼老师出品的零基础汇编视频课程
吉林大学的汇编教程
&lt.还有一些东西忘了(因为你现在才初三;里说 &&gt,编译原理!~;
第六步,但如果你想在一年时间内成为高手:Jsp,将近2年多了;Linux内核入门&gt,
你要有一台自己的电脑才可以哦~: C#.
接近底层的法宝和后续课程的武器!记住,你要加油啊~:
数据结构,反正我现在没见过;&&gt.希望中国的软件产业能发展起来;&gt:
是我们理解整个计算机系统的最佳起点和最有效途径
为编写高效代码打下基础
对深入了解Linux内核提供前提条件
下载工具,英语这些东西也非常重要. (比如:要耐的住寂寞第一步;外国的
&lt,才发现自己还是一只充满好奇的菜鸟.严蔚敏&gt,线性代数.
一定要掌握.(比如,,这个是重中之重,但是你慢慢会发现自己的威力的.殊不知,你可能2年-3年就能达到目标! 我教给你方法,学乾坤大挪移不费力气.就像张无忌一样.,上面的那些就是基础就像&quot?他是如何学会乾坤大挪移.12 赵博士的&
&lt,原因懒的说.只要你有耐心啊,发现没学过的人和你的不一样,我保证你能成为编程高手,你也成不了高手&quot.当你对计算机一窍不通的时候:电驴
好书推荐,成为了别人眼中的高手.
视频推荐.道理是一样的,软件工程.
简直就是上帝禁区,等到高三了,不出3个月就能入门的! 数学;C语言程序设计&gt:
内核.第二步;记得要学会 下载 视频.
学习汇编语言的理由,概念一定要理清,我建议你的数学要超前学习.有多少人愿意去学习那些像天书一样的重要的理论知识的,靠的就是扎实的内功功底.为什么有些人抱怨自己基础差,什么都学不会;如果你准备花5年的时间成为高手;&lt,工欲善其事必先利其器.
里面的内容会改变你的一生.不知道大家记得 张无忌 吗,c++ builder.第一条;&gt. 真羡慕你
提问者评价
最好能告诉我,一些关于C语言设计的软件。
其他类似问题
编程入门的相关知识
按默认排序
其他2条回答
c语言 这是简单的编程语言
您可能关注的推广回答者:回答者:
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁浅谈设计模式&一&& 我们在打造某项产品时,首先要进行产品进行正题构架与设计,然后再到具体实现。是先整体规划,再局部实现。你是想成为一名工人,还是想成为一名产品经理呢?这个取决于你,还是学好设计模式吧。要做一个好的软件人员要懂设计模式,要想成为一名好的产品经理,就必须学好设计模式。让我们开始吧!一、面向对象&& 一名优秀面向对象员同时也将是一名哲学家,一切科学技术都是由最高抽象层到最低实现层的过程。“万事万物皆对象”这句哲学语,似乎包涵了一种巨大的能量。因为他为我们指向了通向整个世界的方向。每每说到这里我很提起《易经》,书中用阴阳衍生出万象,可以解释整个宇宙。道生一,一生二,二生三、三生万物。与计算机的实现原理存在很大的相似性。这其中的关联,我一时也无法说清楚。我似乎想这么说,我们的第一步编程书籍是《易经》,他将是我们控按照我们的编程意识控制世界的一本《编程思想》!很希望将自己也能够写本书,就叫啥《易经的现代科学实现》。& 以上纯属扯淡,下面转入正题!&&&&& POP(Procedure Oriented Program) 面向过程的编程 :只通过控制结构解决问题,数据与函数分离&&& OOP(Object Oriented Program) 面向对象的编程 :数据(属性)与函数(方法)封装在一起&&& AOP(Aspect Oriented Program)面向切面的编程:可以做到对程序的透明过滤1. OOP的三大特点a. 封装性:保证了属性和方法的关联性,是继承性实现的基础b. 继承性:代码的重复利用,提高编程效率。c. 多态性:代码的重复利用时,又能保证了个体的特点和差异。是封装性和继承性的体现。2.包的概念package相当于c和c++中的名字空间,其实就是组织了文件夹的层次结构。调用包,用import 导入。3.类的概念A.类中可以定的内容包括:属性、方法、内部类、内部接口、静态代码块、非静态块、类中声明与顺序无关。B.属性:代表对象所具有的一种特性,例如:人的姓名,年龄。属性的声明语法:&修饰符&*&类型&&名称&=&初始值&;属性可以不声明就使用 ,称为实例变量。属性的赋值的执行顺序:是按在类中的的先后顺序,然后再在构造方法中。在计算机中,对应某一定(ROM)存储单元的数据。& 方法:代表对象所具有行为,例如人的吃,行走等。方法的声明的语法:&修饰符&*&返回类型&&名称&(&参数&*){&功能描叙&} 上述方法在某种意义上对应一种功能和操作,包括在内存单元的操作,及外部设备的操作。对应的是 ROM(数据存储器上的指令集合)另外:每个类都有自己的构造方法,如自己编写的程序的过程中可以不写,的是时候自动调用加缺省的构造函数,缺省的构造函数不带参数,缺省的构造函数内容为空,如果用户自己可以按自己根据程序初始化的需要,自定义构造函数。构造函数作用:用来创建示例对象的方法。 new conductor();C.属性的方法的调用:类内部直接调用,或者使用this关键字,类外部需要使用示例对象来访问,静态成员可以直接用类名来访问。在子类中调用需要使用super。构造方法的调用:需要使用this或者super关键字来代替,尽可在构造函数中调用,必须放在第一句。D.访问权限:类的访问权限& public:所有的文件都可以见和默认的友元函数之后包内可见。一个Java源文件,只能有一个public的类且必须与文件名相同。成员的访问权限 public 所有文件都可以使用&&&&&&&&&&&&&& 默认的 包内可以使用&&&&&&&&&&&&&&& Private 只有类内可以使用&&&&&&&&&&&&&&& Protect 包内及子类可以使用二、面向对象编程原则1.封装变化2.多用组合,少用继承3.针对接口编程,不针对实现编程4.为交互对象之间的松耦合设计而努力5.对扩展开放,对修改关闭6.依赖抽象,不要依赖具体类7.只和朋友交谈8.别找我,我会找你9.类应该只有一个改变的理由三、面向对象编程模式设计模式主要分三个类型:创建型、结构型和行为型。 其中创建型有: &&& 1.Singleton,单例模式:保证一个类只有一个实例,并提供一个访问它的全局访问点 &&& 2.Abstract Factory,抽象工厂:提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们的具体类。 &&& 3.Factory Method,工厂方法:定义一个用于创建对象的接口,让子类决定实例化哪一个类,Factory Method使一个类的实例化延迟到了子类。 &&& 4.Builder,建造模式:将一个复杂对象的构建与他的表示相分离,使得同样的构建过程可以创建不同的表示。&&& 5.Prototype,原型模式:用原型实例指定创建对象的种类,并且通过拷贝这些原型来创建新的对象。 行为型有: &&& 6.Iterator,迭代器模式:提供一个方法顺序访问一个聚合对象的各个元素,而又不需要暴露该对象的内部表示。 &&& 7.Observer,观察者模式:定义对象间一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知自动更新。 &&& 8.Template Method,模板方法:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中,TemplateMethod使得子类可以不改变一个算法的结构即可以重定义该算法得某些特定步骤。 &&& 9.Command,命令模式:将一个请求封装为一个对象,从而使你可以用不同的请求对客户进行参数化,对请求排队和记录请求日志,以及支持可撤销的操作。 &&& 10.State,状态模式:允许对象在其内部状态改变时改变他的行为。对象看起来似乎改变了他的类。 &&& 11.Strategy,策略模式:定义一系列的算法,把他们一个个封装起来,并使他们可以互相替换,本模式使得算法可以独立于使用它们的客户。 &&& 12.China of Responsibility,职责链模式:使多个对象都有机会处理请求,从而避免请求的送发者和接收者之间的耦合关系 &&& 13.Mediator,中介者模式:用一个中介对象封装一些列的对象交互。 &&& 14.Visitor,访问者模式:表示一个作用于某对象结构中的各元素的操作,它使你可以在不改变各元素类的前提下定义作用于这个元素的新操作。 &&& 15.Interpreter,解释器模式:给定一个语言,定义他的文法的一个表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。 &&& 16.Memento,备忘录模式:在不破坏对象的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。 结构型有: &&& 17.Composite,组合模式:将对象组合成树形结构以表示部分整体的关系,Composite使得用户对单个对象和组合对象的使用具有一致性。 &&& 18.Facade,外观模式:为子系统中的一组接口提供一致的界面,fa?ade提供了一高层接口,这个接口使得子系统更容易使用。 &&& 19.Proxy,代理模式:为其他对象提供一种代理以控制对这个对象的访问 &&& 20.Adapter,适配器模式:将一类的接口转换成客户希望的另外一个接口,Adapter模式使得原本由于接口不兼容而不能一起工作那些类可以一起工作。 &&& 21.Decrator,装饰模式:动态地给一个对象增加一些额外的职责,就增加的功能来说,Decorator模式相比生成子类更加灵活。 &&& 22.Bridge,桥模式:将抽象部分与它的实现部分相分离,使他们可以独立的变化。 &&& 23.Flyweight,享元模式:Turbo C 和Visual C++ 6.0 已经是上一个世纪的古董了&br&你现在应该使用最新的MinGW(gcc编译器)或Visual Studio 2013 Express
Turbo C 和Visual C++ 6.0 已经是上一个世纪的古董了你现在应该使用最新的MinGW(gcc编译器)或Visual Studio 2013 Express
来自子话题:
作为快十年前的软工,给一点个人思路吧:&br&&br&1. 不要上手就学C++,先学好C&br&2. 数据结构比任何语言都重要&br&3. 计算机组成原理比任何框架都重要&br&4. 算法很难学好,学好了可能大部分时候都用不上;但你一定要保证需要的时候能够学起来。在关键的机会中,这才是软件行业的杀手锏。&br&5. 软件工程本质是技术+管理,和计算机科学不一样。大学课程很多,选好方向,甚至这个方向可能要根据以后的工作调整。大一大二所有专业课程都要学精深,以后才能了解自己的方向,有侧重。&br&6. 不断地看基础概念,数学,编译原理,温故知新
作为快十年前的软工,给一点个人思路吧:1. 不要上手就学C++,先学好C2. 数据结构比任何语言都重要3. 计算机组成原理比任何框架都重要4. 算法很难学好,学好了可能大部分时候都用不上;但你一定要保证需要的时候能够学起来。在关键的机会中,这才是软件行业…
嵌套的if可以尽量合并,可能换一套逻辑就能减少很多嵌套。同级的if一般可以用多维数组解决。&br&举些栗子(上传代码片段希望公司不要找我麻烦啊。。。):&br&&u&根据不同的交易类型要取不同的值&/u&&br&&img src=&/88f25f25a267a7217b25abac52d9d849_b.jpg& data-rawwidth=&1077& data-rawheight=&363& class=&origin_image zh-lightbox-thumb& width=&1077& data-original=&/88f25f25a267a7217b25abac52d9d849_r.jpg&&&br&&u&根据不同交易类型要做不同的操作&/u&&br&定义函数指针数组,调用的时候根据传入的值调用就行&br&&img src=&/e545dc457d0c53e6dc13a21bee0ca8e8_b.jpg& data-rawwidth=&1063& data-rawheight=&205& class=&origin_image zh-lightbox-thumb& width=&1063& data-original=&/e545dc457d0c53e6dc13a21bee0ca8e8_r.jpg&&&br&&img src=&/4d5d8fb82cdc393f246a8_b.jpg& data-rawwidth=&658& data-rawheight=&143& class=&origin_image zh-lightbox-thumb& width=&658& data-original=&/4d5d8fb82cdc393f246a8_r.jpg&&
嵌套的if可以尽量合并,可能换一套逻辑就能减少很多嵌套。同级的if一般可以用多维数组解决。举些栗子(上传代码片段希望公司不要找我麻烦啊。。。):根据不同的交易类型要取不同的值根据不同交易类型要做不同的操作定义函数指针数组,调用的时候根据传入的值…
从描述来看,显然是你程序有bug,多半还不止一个。至于bug是什么,C语言初学者能犯的千奇百怪的错误太多了,没人能一一列举的。&br&&br&&a data-hash=&c1c892f179f95da8b37a1dcc& href=&/people/c1c892f179f95da8b37a1dcc& class=&member_mention& data-tip=&p$b$c1c892f179f95da8b37a1dcc&&@陈硕&/a& 的答案里说让你把代码贴出来,这个是没错的。但如果你贴一堆代码的话肯定也没人看。所以你要缩小范围,把可能bug定位在5-10行代码之内再贴出来。不过当你做到这点的时候,你自己差不多也意识到哪里出问题了。&br&&br&所以,如同每个大牛的必经之路一样,自己静下心来认认真真debug吧。
从描述来看,显然是你程序有bug,多半还不止一个。至于bug是什么,C语言初学者能犯的千奇百怪的错误太多了,没人能一一列举的。 的答案里说让你把代码贴出来,这个是没错的。但如果你贴一堆代码的话肯定也没人看。所以你要缩小范围,把可能bug定位在5-…
将来是多久? 每种编程语言正如人的思维一样,有其时代局限性。&br&在x86的体系里,C是王者;在Web Browser框架下,Javascript当之无愧。&br&同样的,ActionScript随着Flash的没落而日渐消亡;Perl在几位小弟出现后,也黯然退场;Dephi更是作为时代的悲剧而常常被人悼念。至于Cobol,已经没人再愿意提它。&br&&br&语言的出现通常是为了解决特定领域的问题,比如C语言的出现就是Ken和Dennis为了能免费玩到游戏 (大误)。 在有足够流行度后,问题域的抽象层次越高,范围越宽,其存活的时间也会更久些。 否则,只能看运气:如果其依傍的对象发达了(Objective-C -& Apple),其也会发达一阵;没落了,一样悄声退场(ActionScript -& Flash)。&br&&br&最后, 针对微软的C#、&a href=&http://VB.NET& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&VB.NET&/span&&span class=&invisible&&&/span&&i class=&icon-external&&&/i&&/a&, Oracle的Java、Apple的Obj-C,谈一下个人观点,望能多交流:&br&&ol&&li&最危险的是&a href=&http://VB.NET& class=& external& target=&_blank& rel=&nofollow noreferrer&&&span class=&invisible&&http://&/span&&span class=&visible&&VB.NET&/span&&span class=&invisible&&&/span&&i class=&icon-external&&&/i&&/a&,其实在2年前它已经遭遇过一次危机,但是从微软的角度来看,其没办法同时培养两个语言,何况C#本身就是为其整个跨越10年的.NET战略量身打造的。&br&&/li&&li&Obj-C不一定消亡,但很可能在未来的几年不再火热,甚至掉出TIBCO的TOP10亦有可能,完全取决于苹果的战略。这个世界,总是在开放和封闭(尤其是软硬一体)中不断更替,此起彼落。&/li&&li&Java。Paul大叔曾经将Java和Cobol比对,并预研Java会死亡,那是2003年[1]。如今,在Server和Desktop领域,Java的进展确实相当缓慢。而Android的横空出世,却为这个老迈的语言注入了新的活力。我想,在整个Android生态体系已经建成的时候,Google不太可能那么快放弃Java而改推其他语言。除非有90年代末Java相对于C++那样的契机。&/li&&/ol&&br&参考:&br&[1]:&a href=&/hundred.html& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&The Hundred-Year Language&i class=&icon-external&&&/i&&/a&
将来是多久? 每种编程语言正如人的思维一样,有其时代局限性。在x86的体系里,C是王者;在Web Browser框架下,Javascript当之无愧。同样的,ActionScript随着Flash的没落而日渐消亡;Perl在几位小弟出现后,也黯然退场;Dephi更是作为时代的悲剧而常常被人…
先上图——&img src=&/3c6d0d09ea901fe5e4bebd8b640a5b2a_b.jpg& data-rawwidth=&600& data-rawheight=&328& class=&origin_image zh-lightbox-thumb& width=&600& data-original=&/3c6d0d09ea901fe5e4bebd8b640a5b2a_r.jpg&&&br&很显然,答案的不同和编译器有很大的关系。&br&&br&以下是我自己根据搜集的资料做出的猜想:&br&&br&对于G++,&br&&b&(++i)+(++i)+(++i) &/b&被拆分为 ( & ++i & + & ++i & ) + & ++i &&br&也就是相当于 ( A + A ) + A 的形式。&br&首先由于 ++i 的优先级比较高,先计算第一个 ++i ,这时 ++i 这个算式的结果是4,i = 4 。&br&接下来算第二个 ++i ,这时 ++i 这个&b&算式的结果&/b&是 5 ,i = 5。&br&然后算第一个小括号里的加号,这时 G++ 把 & &b&++i&/b& & 这个算式当作一个整体参与了运算,也就是拿 & ++i & 这个&b&算式的值&/b&参与了运算,也就是 5 + 5 = 10。(可以理解为 G++ 这时把 & ++i & 当作了一个标识符)。&br&最后一个就好算了, i++之后的值是6,i = 6,6 + 10 = 16,所以G++的结果是16。&br&&br&对于VS2008,&br&&b&(++i)+(++i)+(++i) &/b&被拆分为 ( & ++i & + & ++i & + & ++i & ) &br&这个就很好理解了,也是把 & ++i &当作了一个标识符,类似于 A + A + A 的形式。&br&先计算出了这个标识符 A 最终的值,然后进行运算。&br&在三次 & ++i & 之后, & ++i & 的值是6,6 + 6 + 6 = 18。所以VS2008的结果是18.&br&&br&至于JAVA,&br&&b&(++i)+(++i)+(++i) &/b& 可以说没有被拆分&br&每一个 & ++i & 都是一个独立的标识符,这里以一种类似于 A + B + C 的形式进行计算。&br&分别计算出 ABC 的值,然后加在一起。&br&第一个
& ++i & 是 4,第二个 & ++i & 是 5,第三个 & ++i & 是 6,&br&全部计算出以后加起来 4 + 5 + 6 = 15。所以JAVA的结果是15.&br&&br&总而言之,这种差异是由于编译器对自增的不同处理导致的,这也警示我们在敲代码的时候最好不要把自增运算符和其它运算符混用,有时会产生意想不到的效果。&br&&br&============================&br& 13:47 补充: &br&@杨丰羽 说到了&b& s=(++i)+(++i) &/b&这个式子,我也算了一下&img src=&/5c8f1ecaea9d_b.jpg& data-rawwidth=&617& data-rawheight=&298& class=&origin_image zh-lightbox-thumb& width=&617& data-original=&/5c8f1ecaea9d_r.jpg&&&br&G++ 和 VS2008 都是10,因为都是先计算 & ++i & 这个标识符的值,然后相加。&br&JAVA 是 9 ,因为前后两个 & ++i & 在 JAVA 眼中是不一样的,一个是 4 一个是 5 。&br&&br&从这个例子来看,我的猜想似乎是正确的。&br&&br&&br&想要得到准确的答案,需要去看汇编代码,希望能有这方面的高手出现解惑。&br&&br&============================&br& 14:38 补充: &br&@王文远 给出了VS中计算这个式子的汇编代码:&br&&a href=&/question//answer/& class=&internal&&&span class=&invisible&&http://www.&/span&&span class=&visible&&/question/2012&/span&&span class=&invisible&&3835/answer/&/span&&span class=&ellipsis&&&/span&&/a&
先上图——很显然,答案的不同和编译器有很大的关系。以下是我自己根据搜集的资料做出的猜想:对于G++,(++i)+(++i)+(++i) 被拆分为 ( " ++i " + " ++i " ) + " ++i "也就是相当于 ( A + A ) + A 的形式。首先由于 ++i 的优先级比较高,先计算第一个 ++i ,…
来自子话题:
因为5的后面是回车,你第一次读了整数,in-stream pointer(原谅我用这个词)就停在回车前面了,那么你在第二条scanf 一个char的时候,回车就被你读进来了。&br&&br&不同的平台上,这个所谓的「回车 or 换行」,又有不同的case。有的是\r\n,有的是\r,有的是\n。&br&&br&新手请多看一些scanf的例子,特别是它的机理和「expected outcome」,你还没搞懂scanf 一个char究竟是怎么回事,出了问题又不去查书,这根本就误入歧途了。&br&&br&scanf 读一个字符,首先你要知道你要不要过滤掉 leading invisible spaces,根据你现在的程序,我觉得是需要的,你只需要把第二句scanf改成&br&&div class=&highlight&&&pre&&code class=&language-text&&scanf(& %c&,&b);
&/code&&/pre&&/div&就是在%前面加一个空格。&br&&br&为什么要加空格?查手册去。
因为5的后面是回车,你第一次读了整数,in-stream pointer(原谅我用这个词)就停在回车前面了,那么你在第二条scanf 一个char的时候,回车就被你读进来了。不同的平台上,这个所谓的「回车 or 换行」,又有不同的case。有的是\r\n,有的是\r,有的是\n。新…
C 就是结构化的汇编,做 ABI 约定除了 C 基本上没可用的了。(当年还有个 Pascal 可惜倒掉了。)
C 就是结构化的汇编,做 ABI 约定除了 C 基本上没可用的了。(当年还有个 Pascal 可惜倒掉了。)
1. Linux/C程序员表示,经常这么写: if ( 0 == s ).
这完全是合法的。&br&2. 程序出错,一般情况下,先反思自己的代码;神马操作系统/编译器错误,基本不可能。&br&3. 感觉 某K 完全没入门的水平。
“当程序读到else if 这行 要是先碰到 c==2
内存就先开辟空间了” ,如 Kenneth 所述,C是编译再执行的,变量存储的位置早在编译时就已经确定(重定位也差不多),根本就不是读到哪个变量再分配内存的。。。&br&&br&还有,根据我的经验,一般来说,QQ群里面的都是水货,您还是上靠谱点的论坛吧。比如stackoverflow, 国内的cu,感觉还是不错的。
1. Linux/C程序员表示,经常这么写: if ( 0 == s ). 这完全是合法的。2. 程序出错,一般情况下,先反思自己的代码;神马操作系统/编译器错误,基本不可能。3. 感觉 某K 完全没入门的水平。 “当程序读到else if 这行 要是先碰到 c==2 内存就先开辟空间了” …
粘包是中式伪科学吧?
粘包是中式伪科学吧?
Python 是脚本语言,也就是中间件语言,其内核仍然是纯 c 的性能表达的,而主要性能消耗在脚本的实时编译上。&br&而对比c,同样的功能,python可以表达比c更加精炼,当然牺牲了一些性能。&br&如果确实对某个模组性能不满意,还可以使用 c 编写 Python 模块为其加速。&br&面对一些并不需要过多性能而可以获得更快捷的开发速度,Python的优势完全可以盖过“劣势”。&br&可以说,Python基本完美。&br&&br&例如知乎就是使用 Python 制作的。&br&Google 的许多页面也是使用 Python 进行渲染的。
Python 是脚本语言,也就是中间件语言,其内核仍然是纯 c 的性能表达的,而主要性能消耗在脚本的实时编译上。而对比c,同样的功能,python可以表达比c更加精炼,当然牺牲了一些性能。如果确实对某个模组性能不满意,还可以使用 c 编写 Python 模块为其加速…
那得先去找到一个公认牛逼的程序员,然后他客观上C++水平不如平均水平,才能说不准确。
那得先去找到一个公认牛逼的程序员,然后他客观上C++水平不如平均水平,才能说不准确。
对于支持推送的设备来说,设备首先需要有一个全球唯一的身份标志。例如对于iPhone而言,购买手机后,第一次连接网络进行iPhone激活即是苹果服务器为iPhone颁发唯一身份id的过程。&br&&br&简化这个模型,其实有AP和推送服务器两样东西之间也有传输关系。但如果简化,即是iPhone与推送服务器需要实时保持单线唯一的一条联系。当消息抵达后,推送服务器就根据这条保持的联系线路推送给终端的iPhone(当然实际上中间还有AP的参与)。保持推送的条件就是上面第一段所说的,不同设备间的id都是唯一的,不可能有重复,因为一旦重复,这个推送就不知道该推给谁了。(过去在iPhone设备上曾有一个越狱方案是在越狱或破解后由越狱发布者为设备颁发id证书,然而实际上有权颁发合法id证的机构很少,所以越狱发布者为许多设备颁发了重复的id,导致那段时间常有人的qq收到别人莫名其妙的推送信息)&br&&br&这种即时通讯的推送与邮件推送机制是有差异的。另外,为保持推送服务器与手机之间的联系,他们之间每隔一个固定的时间就要发送一次确认对方在线的信息,以保证手机在线。——如果在一个最大时间值后,推送服务器没有再收到手机确认在线的信息,即判定手机推送下线,并不再给手机推送信息,直到下次手机上线为止。&br&&br&——QQ的推送与此又有差异。当iPhone登陆QQ,并且设置推送在线后,服务器上申请了长达2天的在线时间,在这个2天时间内,不管iPhone本身是否在线,QQ都对好友仍显示为在线状态,这就是推送在线。不管在iPhone设备上,QQ软件本身是否运行或iPhone是否连入网络,2天内都显示为在线。&br&&br&与此可进行对比的是:Android或塞班系统,并没有推送机制。我列举一个比较有名的通讯软件,whatsapp。在iPhone和WP的手机上就是如上所述的推送机制,不管whatsapp软件本身是否运行于手机,在打开推送后,手机就能收到whatsapp信息。&br&——但在安卓或塞班上,由于没有推送机制。所以手机必须保证whatsapp软件实时运行于后台,此时消息并不会推送到手机上,而是由手机的whatsapp方面不停地向服务器确认是否有新的消息抵达,当然我这么说可能比较片面。——这种机制与PC上的聊天软件是基本类似的。一旦软件推出或服务停止,收讯就无法达成了。&br&&br&相对而言,推送更为节约资源,不仅相对实时在线和后台来讲更节省流量,并且对本地的手机来讲,也不需要软件运行于后台,手机就有更多余地来运行其他软件。&br&——但缺点是,推送信息抵达手机后,如果你要打开看,通常都需要重新启动软件,这需要时间。&br&&br&——另外,这种机制某种程度上也是由于iOS与WP并不支持真正意义上的多任务造成的,IM通讯软件也没法挂在后台。比如iOS4以后的系统虽然宣称支持多任务,但实际上也只提供7条多任务接口给第三方应用。——IM通讯软件一旦运行于他所谓的后台,是根本不能刷新软件运行的。而安卓和塞班的多任务更类似于桌面操作系统,所以可以挂IM软件。&br&&br&以上个人观点,欢迎高手批评指正。
对于支持推送的设备来说,设备首先需要有一个全球唯一的身份标志。例如对于iPhone而言,购买手机后,第一次连接网络进行iPhone激活即是苹果服务器为iPhone颁发唯一身份id的过程。简化这个模型,其实有AP和推送服务器两样东西之间也有传输关系。但如果简化,…
只有自己写的才算项目经验
只有自己写的才算项目经验
又来妖魔化linux了?
又来妖魔化linux了?
&div class=&highlight&&&pre&&code class=&language-cpp&&&span class=&cp&&#include &map&&/span&
&span class=&cp&&#include &string&&/span&
&span class=&cp&&#include &iostream&&/span&
&span class=&k&&class&/span& &span class=&nc&&IntOrStr&/span& &span class=&p&&{&/span&
&span class=&k&&public&/span&&span class=&o&&:&/span&
&span class=&n&&IntOrStr&/span&&span class=&p&&(&/span&&span class=&kt&&int&/span& &span class=&n&&val&/span&&span class=&p&&)&/span& &span class=&o&&:&/span& &span class=&n&&type_&/span&&span class=&p&&(&/span&&span class=&mi&&0&/span&&span class=&p&&),&/span& &span class=&n&&ival_&/span&&span class=&p&&(&/span&&span class=&n&&val&/span&&span class=&p&&)&/span& &span class=&p&&{}&/span&
&span class=&n&&IntOrStr&/span&&span class=&p&&(&/span&&span class=&k&&const&/span& &span class=&kt&&char&/span&&span class=&o&&*&/span& &span class=&n&&val&/span&&span class=&p&&)&/span& &span class=&o&&:&/span& &span class=&n&&type_&/span&&span class=&p&&(&/span&&span class=&mi&&1&/span&&span class=&p&&),&/span& &span class=&n&&sval_&/span&&span class=&p&&(&/span&&span class=&n&&val&/span&&span class=&p&&)&/span& &span class=&p&&{}&/span&
&span class=&kt&&bool&/span& &span class=&k&&operator&/span& &span class=&o&&&&/span& &span class=&p&&(&/span&&span class=&k&&const&/span& &span class=&n&&IntOrStr&/span&&span class=&o&&&&/span& &span class=&n&&b&/span&&span class=&p&&)&/span& &span class=&k&&const&/span&&span class=&p&&{&/span&
&span class=&k&&if&/span& &span class=&p&&(&/span&&span class=&n&&type_&/span& &span class=&o&&!=&/span& &span class=&n&&b&/span&&span class=&p&&.&/span&&span class=&n&&type_&/span&&span class=&p&&)&/span& &span class=&p&&{&/span&
&span class=&k&&return&/span& &span class=&n&&type_&/span& &span class=&o&&&&/span& &span class=&n&&b&/span&&span class=&p&&.&/span&&span class=&n&&type_&/span&&span class=&p&&;&/span&
&span class=&p&&}&/span& &span class=&k&&else&/span& &span class=&k&&if&/span& &span class=&p&&(&/span&&span class=&n&&type_&/span& &span class=&o&&==&/span& &span class=&mi&&0&/span&&span class=&p&&)&/span& &span class=&p&&{&/span&
&span class=&k&&return&/span& &span class=&n&&ival_&/span& &span class=&o&&&&/span& &span class=&n&&b&/span&&span class=&p&&.&/span&&span class=&n&&ival_&/span&&span class=&p&&;&/span&
&span class=&p&&}&/span& &span class=&k&&else&/span& &span class=&p&&{&/span&
&span class=&k&&return&/span& &span class=&n&&sval_&/span& &span class=&o&&&&/span& &span class=&n&&b&/span&&span class=&p&&.&/span&&span class=&n&&sval_&/span&&span class=&p&&;&/span&
&span class=&p&&}&/span&
&span class=&p&&}&/span&
&span class=&k&&private&/span&&span class=&o&&:&/span&
&span class=&kt&&int&/span& &span class=&n&&type_&/span&&span class=&p&&;&/span&
&span class=&kt&&int&/span& &span class=&n&&ival_&/span&&span class=&p&&;&/span&
&span class=&n&&std&/span&&span class=&o&&::&/span&&span class=&n&&string&/span& &span class=&n&&sval_&/span&&span class=&p&&;&/span&
&span class=&p&&};&/span&
&span class=&kt&&int&/span& &span class=&n&&main&/span&&span class=&p&&()&/span& &span class=&p&&{&/span&
&span class=&n&&std&/span&&span class=&o&&::&/span&&span class=&n&&map&/span&&span class=&o&&&&/span&&span class=&n&&IntOrStr&/span&&span class=&p&&,&/span& &span class=&kt&&int&/span&&span class=&o&&&&/span& &span class=&n&&arr&/span&&span class=&p&&;&/span&
&span class=&n&&arr&/span&&span class=&p&&[&/span&&span class=&s&&&abc&&/span&&span class=&p&&]&/span& &span class=&o&&=&/span& &span class=&mi&&1&/span&&span class=&p&&;&/span&
&span class=&n&&arr&/span&&span class=&p&&[&/span&&span class=&mi&&1&/span&&span class=&p&&]&/span& &span class=&o&&=&/span& &span class=&mi&&2&/span&&span class=&p&&;&/span&
&span class=&n&&std&/span&&span class=&o&&::&/span&&span class=&n&&cout&/span& &span class=&o&&&&&/span& &span class=&n&&arr&/span&&span class=&p&&[&/span&&span class=&s&&&abc&&/span&&span class=&p&&]&/span& &span class=&o&&&&&/span& &span class=&s&&& &&/span& &span class=&o&&&&&/span& &span class=&n&&arr&/span&&span class=&p&&[&/span&&span class=&mi&&1&/span&&span class=&p&&]&/span& &span class=&o&&&&&/span& &span class=&s&&& &&/span& &span class=&o&&&&&/span& &span class=&n&&arr&/span&&span class=&p&&[&/span&&span class=&s&&&1&&/span&&span class=&p&&]&/span& &span class=&o&&&&&/span& &span class=&n&&std&/span&&span class=&o&&::&/span&&span class=&n&&endl&/span&&span class=&p&&;&/span&
&span class=&k&&return&/span& &span class=&mi&&0&/span&&span class=&p&&;&/span&
&span class=&p&&}&/span&
&/code&&/pre&&/div&不谢
#include &map&
#include &string&
#include &iostream&
class IntOrStr {
IntOrStr(int val) : type_(0), ival_(val) {}
IntOrStr(const char* val) : type_(1), sval_(val) {}
bool operator & (const IntOrStr& b) const{
if (type_ != b.…
——————更新,勘误——————&br&&br&&br&昨天晚上回到宿舍谷歌到了官方文档(在机房的时候谷歌挂了,怎么搜都搜不到……),发现之前的解释有个错误,即 &a data-hash=&06d5c84e0cd89e86f7edc& href=&/people/06d5c84e0cd89e86f7edc& class=&member_mention& data-editable=&true& data-title=&@高大月& data-tip=&p$b$06d5c84e0cd89e86f7edc&&@高大月&/a& 同学指出的“原子”语义。我结合昨天写的测试代码再补充一下。&br&&br&我在原来的答案中,有这样的代码:&div class=&highlight&&&pre&&code class=&language-c&&
&span class=&n&&pthread_mutex_unlock&/span&&span class=&p&&(&/span&&span class=&n&&mtx&/span&&span class=&p&&);&/span&
&span class=&n&&pthread_cond_just_wait&/span&&span class=&p&&(&/span&&span class=&n&&cv&/span&&span class=&p&&);&/span&
&span class=&n&&pthread_mutex_lock&/span&&span class=&p&&(&/span&&span class=&n&&mtx&/span&&span class=&p&&);&/span&
&/code&&/pre&&/div&事实上,上面三行代码的并不是pthread_cond_wait(cv, mtx)的内联展开。其中第一行和第二行必须“原子化”,而第三行是可以分离出去的(之所以要把第三行放在里面的原因可以参见原来的答案)。&br&&br&那么为什么第一行和第二行不能分离呢?这是因为必须得保证:&b&如果线程A先进入wait函数(即使没有进入实际的等待状态,比如正在释放mtx),那么必须得保证其他线程在其之后调用的broadcast必须能够将线程A唤醒。&/b&&br&&br&&br&所以,把原来答案中的代码再贴一遍:&div class=&highlight&&&pre&&code class=&language-c&&&span class=&c1&&// 线程A,条件测试&/span&
&span class=&n&&pthread_mutex_lock&/span&&span class=&p&&(&/span&&span class=&n&&mtx&/span&&span class=&p&&);&/span&
&span class=&c1&&// a1&/span&
&span class=&k&&while&/span&&span class=&p&&(&/span&&span class=&n&&pass&/span& &span class=&o&&==&/span& &span class=&mi&&0&/span&&span class=&p&&)&/span& &span class=&p&&{&/span&
&span class=&c1&&// a2 &/span&
&span class=&n&&pthread_mutex_unlock&/span&&span class=&p&&(&/span&&span class=&n&&mtx&/span&&span class=&p&&);&/span&
&span class=&c1&&// a3&/span&
&span class=&n&&pthread_cond_just_wait&/span&&span class=&p&&(&/span&&span class=&n&&cv&/span&&span class=&p&&);&/span& &span class=&c1&&// a4&/span&
&span class=&n&&pthread_mutex_lock&/span&&span class=&p&&(&/span&&span class=&n&&mtx&/span&&span class=&p&&);&/span&
&span class=&c1&&// a5&/span&
&span class=&p&&}&/span&
&span class=&n&&pthread_mutex_unlock&/span&&span class=&p&&(&/span&&span class=&n&&mtx&/span&&span class=&p&&);&/span&
&span class=&c1&&// 线程B,条件发生修改,对应的signal代码&/span&
&span class=&n&&pthread_mutex_lock&/span&&span class=&p&&(&/span&&span class=&n&&mtx&/span&&span class=&p&&);&/span&
&span class=&c1&&// b1&/span&
&span class=&n&&pass&/span& &span class=&o&&=&/span& &span class=&mi&&1&/span&&span class=&p&&;&/span&
&span class=&c1&&// b2&/span&
&span class=&n&&pthread_mutex_unlock&/span&&span class=&p&&(&/span&&span class=&n&&mtx&/span&&span class=&p&&);&/span& &span class=&c1&&// b3&/span&
&span class=&n&&pthread_cond_signal&/span&&span class=&p&&(&/span&&span class=&n&&cv&/span&&span class=&p&&);&/span&
&span class=&c1&&// b4&/span&
&/code&&/pre&&/div&&br&如果执行序列是:a1, a2, a3, b1, b2, b3, b4, a4,那么线程A将不会被唤醒。而a3在线程B之前执行,这意味着wait函数是在signal之前调用的,所以不满足上文提到的保证。&br&&br&&b&解决办法:&/b&&br&&ol&&li&先将线程附加到等待队列&/li&&li&释放mutex&/li&&li&进入等待&/li&&/ol&感兴趣的同学的可以看下源码(&a href=&http://www.oschina.net/code/explore/clamav-0.96.5/win32/3rdparty/pthreads/pthread_cond_wait.c& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&pthread_cond_wait.c&i class=&icon-external&&&/i&&/a&),附加到等待队列这个操作是加锁的,所以可以保证之前发起的signal不会错误得唤醒本线程,而之后发起的signal必然唤醒本线程。&br&&br&因此,下面的代码是绝对不会出错的:&div class=&highlight&&&pre&&code class=&language-text&&// 线程A,条件测试
pthread_mutex_lock(mtx);
while(pass == 0) {
pthread_cond_wait(cv, mtx); // a3
pthread_mutex_unlock(mtx);
// 线程B,条件发生修改,对应的signal代码
pthread_mutex_lock(mtx);
pthread_mutex_unlock(mtx); // b3
pthread_cond_signal(cv);
&/code&&/pre&&/div&如果线程A先运行,那么执行序列必然是:a1, a2, a3, b1, b2, b3, b4, a4。&br&如果线程B先运行,那么执行序列可能是:b1, b2, b3, b4, a1, a2, a4&br&也可能是:b1, b2, b3, a1, a2, a3, b4, a4&br&&br&所以,如果是我设计pthread API,那么我会添加一个pthread_cond_unlock_and_wait函数,伪代码如下:&br&&div class=&highlight&&&pre&&code class=&language-c&&&span class=&kt&&int&/span& &span class=&nf&&pthread_cond_wait&/span&&span class=&p&&(&/span&&span class=&n&&cv&/span&&span class=&p&&,&/span& &span class=&n&&mtx&/span&&span class=&p&&)&/span& &span class=&p&&{&/span&
&span class=&kt&&int&/span& &span class=&n&&ret&/span& &span class=&o&&=&/span& &span class=&n&&pthread_cond_unlock_and_wait&/span&&span class=&p&&(&/span&&span class=&n&&cv&/span&&span class=&p&&,&/span& &span class=&n&&mtx&/span&&span class=&p&&);&/span&
&span class=&n&&pthread_mutex_lock&/span&&span class=&p&&(&/span&&span class=&n&&mtx&/span&&span class=&p&&);&/span&
&span class=&k&&return&/span& &span class=&n&&ret&/span&&span class=&p&&;&/span&
&span class=&p&&}&/span&
&span class=&c1&&// 线程A,条件测试&/span&
&span class=&n&&pthread_mutex_lock&/span&&span class=&p&&(&/span&&span class=&n&&mtx&/span&&span class=&p&&);&/span&
&span class=&k&&if&/span& &span class=&p&&(&/span&&span class=&n&&pass&/span& &span class=&o&&==&/span& &span class=&mi&&0&/span&&span class=&p&&)&/span&
&span class=&n&&pthread_cond_unlock_and_wait&/span&&span class=&p&&(&/span&&span class=&n&&cv&/span&&span class=&p&&,&/span& &span class=&n&&mtx&/span&&span class=&p&&);&/span&
&span class=&k&&else&/span&
&span class=&n&&pthread_mutex_unlock&/span&&span class=&p&&(&/span&&span class=&n&&mtx&/span&&span class=&p&&);&/span&
&span class=&c1&&// 线程B,条件发生修改,对应的signal代码&/span&
&span class=&n&&pthread_mutex_lock&/span&&span class=&p&&(&/span&&span class=&n&&mtx&/span&&span class=&p&&);&/span&
&span class=&c1&&// b1&/span&
&span class=&n&&pass&/span& &span class=&o&&=&/span& &span class=&mi&&1&/span&&span class=&p&&;&/span&
&span class=&c1&&// b2&/span&
&span class=&n&&pthread_mutex_unlock&/span&&span class=&p&&(&/span&&span class=&n&&mtx&/span&&span class=&p&&);&/span& &span class=&c1&&// b3&/span&
&span class=&n&&pthread_cond_signal&/span&&span class=&p&&(&/span&&span class=&n&&cv&/span&&span class=&p&&);&/span&
&span class=&c1&&// b4&/span&
&/code&&/pre&&/div&这样的好处在于:如果我们可以保证没有虚假唤醒(即不需要while循环测试条件),那么我们可以将线程A的代码改成上述形式,这样无论怎样都只需要执行一次pthread_mutex_unlock()函数,而之前的版本至少需要执行两次。&br&&br&&br&—————— 原来的答案——————&br&&br&感谢大家的回答!&br&看了之后,我获得了启发,突然觉得这或许是跟条件变量的通常用法有关。&br&&br&首先需要明白两点:&br&&ul&&li&wait()操作通常伴随着条件检测,如:&div class=&highlight&&&pre&&code class=&language-c&&&span class=&k&&while&/span&&span class=&p&&(&/span&&span class=&n&&pass&/span& &span class=&o&&==&/span& &span class=&mi&&0&/span&&span class=&p&&)&/span&
&span class=&n&&pthread_cond_wait&/span&&span class=&p&&(...);&/span&
&/code&&/pre&&/div&&/li&&li&signal*()函数通常伴随着条件改变,如:&div class=&highlight&&&pre&&code class=&language-c&&&span class=&n&&pass&/span& &span class=&o&&=&/span& &span class=&mi&&1&/span&&span class=&p&&;&/span&
&span class=&n&&pthread_cond_signal&/span&&span class=&p&&(...)&/span&
&/code&&/pre&&/div&&br&&/li&&/ul&由于此两处都涉及到变量pass,所以为了防止Race Condition,必须得加锁。所以代码会变成下面这样:&div class=&highlight&&&pre&&code class=&language-c&&&span class=&c1&&// 条件测试&/span&
&span class=&n&&pthread_mutex_lock&/span&&span class=&p&&(&/span&&span class=&n&&mtx&/span&&span class=&p&&);&/span&
&span class=&k&&while&/span&&span class=&p&&(&/span&&span class=&n&&pass&/span& &span class=&o&&==&/span& &span class=&mi&&0&/span&&span class=&p&&)&/span&
&span class=&n&&pthread_cond_wait&/span&&span class=&p&&(...);&/span&
&span class=&n&&pthread_mutex_unlock&/span&&span class=&p&&(&/span&&span class=&n&&mtx&/span&&span class=&p&&);&/span&
&span class=&c1&&// 条件发生修改,对应的signal代码&/span&
&span class=&n&&pthread_mutex_lock&/span&&span class=&p&&(&/span&&span class=&n&&mtx&/span&&span class=&p&&);&/span&
&span class=&n&&pass&/span& &span class=&o&&=&/span& &span class=&mi&&1&/span&&span class=&p&&;&/span&
&span class=&n&&pthread_mutex_unlock&/span&&span class=&p&&(&/span&&span class=&n&&mtx&/span&&span class=&p&&);&/span&
&span class=&n&&pthread_cond_signal&/span&&span class=&p&&(...);&/span&
&/code&&/pre&&/div&&br&然后,我们假设wait()操作不会自动释放、获取锁,那么代码会变成这样:&div class=&highlight&&&pre&&code class=&language-c&&&span class=&c1&&// 条件测试&/span&
&span class=&n&&pthread_mutex_lock&/span&&span class=&p&&(&/span&&span class=&n&&mtx&/span&&span class=&p&&);&/span&
&span class=&k&&while&/span&&span class=&p&&(&/span&&span class=&n&&pass&/span& &span class=&o&&==&/span& &span class=&mi&&0&/span&&span class=&p&&)&/span& &span class=&p&&{&/span&
&span class=&n&&pthread_mutex_unlock&/span&&span class=&p&&(&/span&&span class=&n&&mtx&/span&&span class=&p&&);&/span&
&span class=&n&&pthread_cond_just_wait&/span&&span class=&p&&(&/span&&span class=&n&&cv&/span&&span class=&p&&);&/span&
&span class=&n&&pthread_mutex_lock&/span&&span class=&p&&(&/span&&span class=&n&&mtx&/span&&span class=&p&&);&/span&
&span class=&p&&}&/span&
&span class=&n&&pthread_mutex_unlock&/span&&span class=&p&&(&/span&&span class=&n&&mtx&/span&&span class=&p&&);&/span&
&span class=&c1&&// 条件发生修改,对应的signal代码&/span&
&span class=&n&&pthread_mutex_lock&/span&&span class=&p&&(&/span&&span class=&n&&mtx&/span&&span class=&p&&);&/span&
&span class=&n&&pass&/span& &span class=&o&&=&/span& &span class=&mi&&1&/span&&span class=&p&&;&/span&
&span class=&n&&pthread_mutex_unlock&/span&&span class=&p&&(&/span&&span class=&n&&mtx&/span&&span class=&p&&);&/span&
&span class=&n&&pthread_cond_signal&/span&&span class=&p&&(&/span&&span class=&n&&cv&/span&&span class=&p&&);&/span&
&/code&&/pre&&/div&&br&久而久之,程序员发现unlock, just_wait, lock这三个操作始终得在一起。于是就提供了一个pthread_cond_wait()函数来同时完成这三个函数。&br&&br&另外一个证据是,signal()函数是不需要传递mutex参数的,所以关于mutex参数是用于同步wait()和signal()函数的说法更加站不住脚。&br&&br&所以我的结论是:&b&传递的mutex并不是为了防止wait()函数内部的Race Condition!而是因为调用wait()之前你总是获得了某个mutex(例如用于解决此处pass变量的Race Condition的mutex),并且这个mutex在你调用wait()之前必须得释放掉,调用wait()之后必须得重新获取。&/b&&br&&br&&br&&b&所以,pthread_cond_wait()函数不是一个细粒度的函数,却是一个实用的函数。&/b&
——————更新,勘误——————昨天晚上回到宿舍谷歌到了官方文档(在机房的时候谷歌挂了,怎么搜都搜不到……),发现之前的解释有个错误,即
同学指出的“原子”语义。我结合昨天写的测试代码再补充一下。我在原来的答案中,有这样的代码: …
图灵完全是在可计算性上说C语言能够和图灵机等价,但是并不意味着C语言能够实现所有的功能。算法是一个高层次的问题,所以所有的高级语言在实现(可解的)算法上并不存在能和不能的问题,只有方便和不方便的问题。&br&&br&但是往下层的话,C语言就有很多实现不了的了。比如,直接读写控制寄存器,C语言就做不到了,必须内联汇编或者通过其他接口来实现。
图灵完全是在可计算性上说C语言能够和图灵机等价,但是并不意味着C语言能够实现所有的功能。算法是一个高层次的问题,所以所有的高级语言在实现(可解的)算法上并不存在能和不能的问题,只有方便和不方便的问题。但是往下层的话,C语言就有很多实现不了的…
C 语言是为 Unix 系统而设计的。或者反过来说 Unix 系统是为 C 语言设计的。&br&&br&FILE 其实是个实心数据结构,跟对象的概念类似,它封装的是基于 fd 文件句柄的底层调用。&br&&br&每个进程拥有独立的内存空间,同时每个进程来也拥有独立的 fd 号码,一般 stdin, stdout, stderr 的 fd 号码是 0, 1, 2,如果之后打开了其它的文件,文件句柄号会累加。&br&&br&简单的说,他们所指向的文件句柄的值是 0, 1, 2 。
C 语言是为 Unix 系统而设计的。或者反过来说 Unix 系统是为 C 语言设计的。FILE 其实是个实心数据结构,跟对象的概念类似,它封装的是基于 fd 文件句柄的底层调用。每个进程拥有独立的内存空间,同时每个进程来也拥有独立的 fd 号码,一般 stdin, stdout, …
C语言配合TCC完全可以当脚本用了,TCC编译linux内核也就10几秒。
C语言配合TCC完全可以当脚本用了,TCC编译linux内核也就10几秒。

我要回帖

更多关于 linux下编译c程序 的文章

 

随机推荐