几个小问题

来源:互联网 发布:鼎信网络充值专营店 编辑:程序博客网 时间:2024/05/14 21:33

(1)pthread_mutex_t 类型的初始化问题

两种方式:

     静态初始化:一般是静态变量时,如果用于初始化结构体中的某个成员变量时,只能在创建结构体变量时使用(注意不是赋值)。

     动态初始化:

该函数用于C函数的多线程编程中,互斥锁的初始化。 
头文件:#include <pthread.h>
函数原型: int pthread_mutex_init(pthread_mutex_t *restrict mutex,const pthread_mutexattr_t *restrict attr);
pthread_mutex_init() 函数是以动态方式创建互斥锁的,参数attr指定了新建互斥锁的属性。如果参数attr为空,则使用默认的互斥锁属性,默认属性为快速互斥锁 。互斥锁的属性在创建锁的时候指定,在LinuxThreads实现中仅有一个锁类型属性,不同的锁类型在试图对一个已经被锁定的互斥锁加锁时表现不同。
pthread_mutexattr_init() 函数成功完成之后会返回零,其他任何返回值都表示出现了错误。
函数成功执行后,互斥锁被初始化为未锁住态
      如果用默认属性,可以直接用 pthread_mutex_init(&mutex,NULL);初始化即可。

   在静态分配时,比如全局变量,我们必须将它初始化为PTHREAD_MUTEX_INITIALIZER,而如果在共享内存中分配时,必须用pthread_mutex_init来初始化。 在pthread.h头文件中PTHREAD_MUTEX_INITIALIZER是这样定义的: # define PTHREAD_MUTEX_INITIALIZER / { { 0, 0, 0, 0, 0, 0, { 0, 0 } } } 如果不对其进行初始化,对于某些系统来说如Solaris,静态分配就是初始化为零,所以没什么问题。但并非所有的系统都是这样的,如Digtal Unix将初始化常值定义为非0。

(2)整理动态处理内存不足问题


(3)嵌入式中像 NULL这种定义要自己定义?

下面是/usr /include/linux下的stddef.h文件中的NULL定义:

#undef NULL
#if defined(__cplusplus)
#define NULL 0
#else
#define NULL ((void *)0)
#endif

嵌入式Linux一般没必要有include文件,具体编译时需要的include可以在工具链中,工具链中的头文件一般都是标准定义,但是像数据类型等可以自己定义,自己定义时避免与标准定义中的重复。使用时根据选择使用标准定义还是自己的定义,但是像NULL这种如果标准头文件就有了就不需要自己定了,除非想使用他的其他定义方式。

1.Linux头文件一般在那些位置,以及程序如何找到他们

(转载)

Linux C语言头文件搜索路径

    本文介绍在linux中头文件的搜索路径,也就是说你通过include指定的头文件,linux下的gcc编译器它是怎么找到它的呢。在此之前,先了解一个基本概念。

    头文件是一种文本文件,使用文本编辑器将代码编写好之后,以扩展名.h保存就行了。头文件中一般放一些重复使用的代码,例如函数声明、变量声明、常数定义、宏的定义等等。当使用#include语句将头文件引用时,相当于将头文件中所有内容,复制到#include处。#include有两种写法形式,分别是:

#include <> : 直接到系统指定的某些目录中去找某些头文件。

#include “” : 先到源文件所在文件夹去找,然后再到系统指定的某些目录中去找某些头文件。

    

    #include文件可能会带来一个问题就是重复应用,如a.h引用的一个函数是某种实现,而b.h引用的这个函数却是另外一种实现,这样在编译的时候将会出现错误。所以,为了避免因为重复引用而导致的编译错误,头文件常具有:

#ifndef    LABEL

#define    LABEL

    //代码部分

#endif

的格式。其中LABEL为一个唯一的标号,命名规则跟变量的命名规则一样。常根据它所在的头文件名来命名,例如,如果头文件的文件名叫做hardware.h,那么可以这样使用:

#ifndef    __HARDWARE_H__

#define    __HARDWARE_H__

  //代码部分

#endif

这样写的意思就是,如果没有定义__HARDWARE_H__,则定义__HARDWARE_H__,并编译下面的代码部分,直到遇到#endif。这样当重复引用时,由于__HARDWARE_H__已经被定义,则下面的代码部分就不会被编译了,这样就避免了重复定义。

 

    一句话,头文件事实上只是把一些常用的命令集成在里面,你要用到哪方面的命令就载入哪个头文件就可以了。

 

    gcc寻找头文件的路径(按照1->2->3的顺序)

    1. 在gcc编译源文件的时候,通过参数-I指定头文件的搜索路径,如果指定路径有多个路径时,则按照指定路径的顺序搜索头文件。命令形式如:“gcc -I /path/where/theheadfile/in sourcefile.c“,这里源文件的路径可以是绝对路径,也可以是相对路径。eg:

设当前路径为/root/test,include_test.c如果要包含头文件“include/include_test.h“,有两种方法:

1) include_test.c中#include “include/include_test.h”或者#include "/root/test/include/include_test.h",然后gcc include_test.c即可

2) include_test.c中#include <include_test.h>或者#include <include_test.h>,然后gcc –I include include_test.c也可

 

    2. 通过查找gcc的环境变量C_INCLUDE_PATH/CPLUS_INCLUDE_PATH/OBJC_INCLUDE_PATH来搜索头文件位置。

 

    3. 再找内定目录搜索,分别是

/usr/include

/usr/local/include

/usr/lib/gcc-lib/i386-linux/2.95.2/include

最后一行是gcc程序的库文件地址,各个用户的系统上可能不一样。

    gcc在默认情况下,都会指定到/usr/include文件夹寻找头文件。

    gcc还有一个参数:-nostdinc,它使编译器不再系统缺省的头文件目录里面找头文件,一般和-I联合使用,明确限定头文件的位置。在编译驱动模块时,由于非凡的需求必须强制GCC不搜索系统默认路径,也就是不搜索/usr/include要用参数-nostdinc,还要自己用-I参数来指定内核头文件路径,这个时候必须在Makefile中指定。


    4. 当#include使用相对路径的时候,gcc最终会根据上面这些路径,来最终构建出头文件的位置。如#include <sys/types.h>就是包含文件/usr/include/sys/types.h

2.如何查看gcc定义的宏

(转载)
使用如下目录:
  cpp -dM /dev/null
数据结果示例:
#define __DBL_MIN_EXP__ (-1021)#define __UINT_LEAST16_MAX__ 65535...#define __unix__ 1#define __x86_64 1
...
注意:
结果中并不包括以下大家经常使用的宏哦。
__FUNCTION__       所在函数的函数名称    (字符串) __LINE__          所在行的行号          (数字) __FILE__          所在文件名称          (字符串) 
__DATE__           编译的时的日期        (字符串,例如"Nov 29 2012")
__TIME__           编译时的时间           (字符串,例如"15:05:25")

(4)整理自己的打印函数,看看一般嵌入式中的打印函数是怎么实现的?


原创粉丝点击