2015-07-21 22:55:30 u010258235 阅读数 2692

abs(计算整型数的绝对值)

  相关函数  labs, fabs

  表头文件  #include<stdlib.h>

  定义函数  int abs (int j)

  函数说明  abs()用来计算参数j的绝对值,然后将结果返回。

  返回值  返回参数j的绝对值结果。

  范例  #ingclude <stdlib.h>

  main(){

  int ansert;

  answer = abs(-12);

  printf("|-12| = %d\n", answer);

  }

  执行  |-12| = 12

  acos(取反余弦函数数值)

  相关函数  asin , atan , atan2 , cos , sin , tan

  表头文件  #include <math.h>

  定义函数  double acos (double x);

  函数说明  acos()用来计算参数x的反余弦值,然后将结果返回。参数x范围为-11之间,超过此范围则会失败。

  返回值  返回0PI之间的计算结果,单位为弧度,在函数库中角度均以弧度来表示。

  错误代码  EDOM参数x超出范围。

  附加说明  使用GCC编译时请加入-lm

  范例  #include <math.h>

  main (){

  double angle;

  angle = acos(0.5);

  printf("angle = %f\n", angle);

  }

  执行  angle = 1.047198

  asin(取反正弦函数值)

  相关函数  acos , atan , atan2 , cos , sin , tan

  表头文件  #include <math.h>

  定义函数  double asin (double x)

  函数说明  asin()用来计算参数x的反正弦值,然后将结果返回。参数x范围为-11之间,超过此范围则会失败。

  返回值  返回-PI/2PI/2之间的计算结果。

  错误代码  EDOM参数x超出范围

  附加说明  使用GCC编译时请加入-lm

  范例  #include<math.h>

  main()

  {

  double angle;

  angle = asin (0.5);

  printf("angle = %f\n",angle);

  }

  执行  angle = 0.523599

  atan(取反正切函数值)

  相关函数  acosasinatan2cossintan

  表头文件  #include<math.h>

  定义函数  double atan(double x);

  函数说明  atan()用来计算参数x的反正切值,然后将结果返回。

  返回值  返回-PI/2PI/2之间的计算结果。

  附加说明  使用GCC编译时请加入-lm

  范例  #include<math.h>

  main()

  {

  double angle;

  angle =atan(1);

  printf("angle = %f\n",angle);

  }

  执行  angle = 1.570796

  atan2(取得反正切函数值)

  相关函数  acosasinatancossintan

  表头文件  #include<math.h>

  定义函数  double atan2(double y,double x);

  函数说明  atan2()用来计算参数y/x的反正切值,然后将结果返回。

  返回值  返回-PI/2 PI/2 之间的计算结果。

  附加说明  使用GCC编译时请加入-lm

  范例  #include<math.h>

  main()

  {

  double angle;

  angle = atan2(1,2);

  printf("angle = %f\n", angle);

  }

  执行  angle = 0.463648

  ceil(取不小于参数的最小整型数)

  相关函数  fabs

  表头文件  #include <math.h>

  定义函数  double ceil (double x);

  函数说明  ceil()会返回不小于参数x的最小整数值,结果以double形态返回。

  返回值  返回不小于参数x的最小整数值。

  附加说明  使用GCC编译时请加入-lm

  范例  #include<math.h>

  main()

  {

  double value[ ]={4.8,1.12,-2.2,0};

  int i;

  for (i=0;value[i]!=0;i++)

  printf("%f=>%f\n",value[i],ceil(value[i]));

  }

  执行  4.800000=>5.000000

  1.120000=>2.000000

  -2.200000=>-2.000000

  cos(取余玄函数值)

  相关函数  acosasinatanatan2sintan

  表头文件  #include<math.h>

  定义函数  double cos(double x);

  函数说明  cos()用来计算参数x 的余玄值,然后将结果返回。

  返回值  返回-11之间的计算结果。

  附加说明  使用GCC编译时请加入-lm

  范例  #include<math.h>

  main()

  {

  double answer = cos(0.5);

  printf("cos (0.5) = %f\n",answer);

  }

  执行  cos(0.5) = 0.877583

  cosh(取双曲线余玄函数值)

  相关函数  sinhtanh

  表头文件  #include<math.h>

  定义函数  double cosh(double x);

  函数说明  cosh()用来计算参数x的双曲线余玄值,然后将结果返回。数学定义式为:(exp(x)+exp(-x))/2

  返回值  返回参数x的双曲线余玄值。

  附加说明  使用GCC编译时请加入-lm

  范例  #include<math.h>

  main()

  {

  double answer = cosh(0.5);

  printf("cosh(0.5) = %f\n",answer);

  }

  执行  cosh(0.5) = 1.127626

  exp(计算指数)

  相关函数  loglog10pow

  表头文件  #include<math.h>

  定义函数  double exp(double x);

  函数说明  exp()用来计算以e为底的x次方值,即ex值,然后将结果返回。

  返回值  返回ex次方计算结果。

  附加说明  使用GCC编译时请加入-lm

  范例  #include<math.h>

  main()

  {

  double answer;

  answer = exp (10);

  printf("e^10 =%f\n", answer);

  }

  执行  e^10 = 22026.465795

  frexp(将浮点型数分为底数与指数)

  相关函数  ldexpmodf

  表头文件  #include<math.h>

  定义函数  double frexp( double x, int *exp);

  函数说明  frexp()用来将参数x 的浮点型数切割成底数和指数。底数部分直接返回,指数部分则借参数exp 指针返回,将返回值乘以2 exp次方即为x的值。

  返回值  返回参数x的底数部分,指数部分则存于exp指针所指的地址。

  附加说明  使用GCC编译时请加入-lm

  范例  #include <math.h>

  main()

  {

  int exp;

  double fraction;

  fraction = frexp (1024,&exp);

  printf("exp = %d\n",exp);

  printf("fraction = %f\n", fraction);

  }

  执行  exp = 11

  fraction = 0.500000 /* 0.5*(2^11)=1024*/

  ldexp(计算2的次方值)

  相关函数  frexp

  表头文件  #include<math.h>

  定义函数  double ldexp(double x,int exp);

  函数说明  ldexp()用来将参数x乘上2exp次方值,即x*2exp

  返回值  返回计算结果。

  附加说明  使用GCC编译时请加入-lm

  范例:  /* 计算3*(2^2)12 */

  #include<math.h>

  main()

  {

  int exp;

  double x,answer;

  answer = ldexp(3,2);

  printf("3*2^(2) = %f\n",answer);

  }

  执行  3*2^(2) = 12.000000

  log(计算以e 为底的对数值)

  相关函数  explog10pow

  表头文件  #include <math.h>

  定义函数  double log (double x);

  函数说明  log()用来计算以e为底的x 对数值,然后将结果返回。

  返回值  返回参数x的自然对数值。

  错误代码  EDOM 参数x为负数,ERANGE 参数x为零值,零的对数值无定义。

  附加说明  使用GCC编译时请加入-lm

  范例  #include<math.h>

  main()

  {

  double answer;

  answer = log (100);

  printf("log(100) = %f\n",answer);

  }

  执行  log(100) = 4.605170

  log10(计算以10 为底的对数值)

  相关函数  explogpow

  表头文件  #include<math.h>

  定义函数  double log10(double x);

  函数说明  log10()用来计算以10为底的x对数值,然后将结果返回。

  返回值  返回参数x10为底的对数值。

  错误代码  EDOM参数x为负数。RANGE参数x为零值,零的对数值无定义。

  附加说明  使用GCC编译时请加入-lm

  范例  #include<math.h>

  main()

  {

  double answer;

  answer = log10(100);

  printf("log10(100) = %f\n",answer);

  }

  执行  log10(100) = 2.000000

  pow(计算次方值)

  相关函数  exploglog10

  表头文件  #include<math.h>

  定义函数  double pow(double x,double y);

  函数说明  pow()用来计算以x为底的y次方值,即xy值,然后将结果返回。

  返回值  返回xy次方计算结果。

  错误代码  EDOM 参数x为负数且参数y不是整数。

  附加说明  使用GCC编译时请加入-lm

  范例  #include <math.h>

  main()

  {

  double answer;

  answer =pow(2,10);

  printf("2^10 = %f\n", answer);

  }

  执行  2^10 = 1024.000000

   sin(取正玄函数值)

  相关函数  acosasinatanatan2costan

  表头文件  #include<math.h>

  定义函数  double sin(double x);

  函数说明  sin()用来计算参数x的正玄值,然后将结果返回。

  返回值  返回-1 1之间的计算结果。

  附加说明  使用GCC编译时请加入-lm

  范例  #include<math.h>

  main()

  {

  double answer = sin (0.5);

  printf("sin(0.5) = %f\n",answer);

  }

  执行  sin(0.5) = 0.479426

  sinh(取双曲线正玄函数值)

  相关函数  coshtanh

  表头文件  #include<math.h>

  定义函数  double sinh( double x);

  函数说明  sinh()用来计算参数x的双曲线正玄值,然后将结果返回。数学定义式为:(exp(x)-exp(-x))/2

  返回值  返回参数x的双曲线正玄值。

  附加说明  使用GCC编译时请加入-lm

  范例  #include<math.h>

  main()

  {

  double answer = sinh (0.5);

  printf("sinh(0.5) = %f\n",answer);

  }

  执行  sinh(0.5) = 0.521095

  sqrt(计算平方根值)

  相关函数  hypotq

  表头文件  #include<math.h>

  定义函数  double sqrt(double x);

  函数说明  sqrt()用来计算参数x的平方根,然后将结果返回。参数x必须为正数。

  返回值  返回参数x的平方根值。

  错误代码  EDOM 参数x为负数。

  附加说明  使用GCC编译时请加入-lm

  范例  /* 计算200的平方根值*/

  #include<math.h>

  main()

  {

  double root;

  root = sqrt (200);

  printf("answer is %f\n",root);

  }

  执行  answer is 14.142136

  tan(取正切函数值)

  相关函数  atanatan2cossin

  表头文件  #include <math.h>

  定义函数  double tan(double x);

  函数说明  tan()用来计算参数x的正切值,然后将结果返回。

  返回值  返回参数x的正切值。

  附加说明  使用GCC编译时请加入-lm

  范例  #include<math.h>

  main()

  {

  double answer = tan(0.5);

  printf("tan (0.5) = %f\n",answer);

  }

  执行  tan(0.5) = 0.546302

  tanh(取双曲线正切函数值)

  相关函数  coshsinh

  表头文件  #include<math.h>

  定义函数  double tanh(double x);

  函数说明  tanh()用来计算参数x的双曲线正切值,然后将结果返回。数学定义式为:sinh(x)/cosh(x)

  返回值  返回参数x的双曲线正切值。

  附加说明  使用GCC编译时请加入-lm

  范例  #include<math.h>

  main()

  {

  double answer = tanh(0.5);

  printf("tanh(0.5) = %f\n",answer);

  }

  执行  tanh(0.5) = 0.462117

2014-09-18 16:51:29 luotuo44 阅读数 10069

        转载请注明出处: http://blog.csdn.net/luotuo44/article/details/39374759


        本文主要涉及Linux时间类型、时间函数以及Linux提供的睡眠函数。

 

时间类型和对应的函数:

time_t:

        最不陌生的时间类型恐怕是time_t这个类型了吧。它出现在C语言的标准库。但ISO C中并没有规定time_t是什么类型、范围以及精度,不过在POSIX中一般是被实现为有符号的整型。

        time_t的单位是秒。函数time()的返回值就是一个time_t类型,表示从1970-01-01 00:00:00 UTC (即Epoch时间)到现在有多少秒。要注意的是,该函数返回的是一个UTC时间,不是我们平常使用的北京时间。可以用函数localtime把这个UTC时间转换成当地时间。我们可以用这个函数把UTC时间转换成北京时间。localtime的返回值是一个struct  tm结构体指针。定义如下:

struct tm {
	int tm_sec;    /* 秒 [0-60] 有闰秒*/
	int tm_min;    /* 分钟 [0-59] */
	int tm_hour;   /* 小时 [0-23) */
	int tm_mday;   /* 日 [1-31) */
	int tm_mon;    /*月 [0-11) */
	int tm_year;   /* 年 其值等于所在年份- 1900 */
	int tm_wday;   /* 星期 ]0-6] 星期天为0 */
	int tm_yday;   /* 今天是今年的第几天 [0-365]  1月1日是第0天*/
	int tm_isdst;  /* 夏令时标志位*/
};

        注意各个成员的范围,不要搞错了。此外,对于秒,是有闰秒的。所以范围是[0, 60]。

        可以看到,相对于一个time_t,这个struct  tm结构体的成员还是很有用的。因为一个给定time_t,人们根本就不知道它表示的是哪个时间,但转换成struct  tm结构体后就能一眼看出是什么时间。

        如果并不想把时间转换成本地时间,而仅仅转换成struct tm,那么可以使用函数gmtime,它同样是返回一个struct tm指针。因为localtime和gmtime都是返回一个指针,所以它们都不是线程安全的。对于地,有localtime_r和gmtime_r。这个两个函数是线程安全的。如果像把一个struct tm时间转换成time_t可以使用mktime函数。有时也想把用这个时间类型转换成一个字符串方便输出,标准C语言也提供了这些函数。下面给出这些函数的声明。

char *asctime(const struct tm *tm);
char *asctime_r(const struct tm *tm, char *buf);

char *ctime(const time_t *timep);
char *ctime_r(const time_t *timep, char *buf);

struct tm *gmtime(const time_t *timep);
struct tm *gmtime_r(const time_t *timep, struct tm *result);

struct tm *localtime(const time_t *timep);
struct tm *localtime_r(const time_t *timep, struct tm *result);

time_t mktime(struct tm *tm);

        一般来说,这些函数都是在time.h头文件中。但对于线程安全的那几个函数,有些编译器还要另外#include<pthread.h>。



clock_t:

        它的实际类型是有符号整型,它一般是用来表示一个进程占用的CPU时间。函数clock()返回就一个clock_t类型值,表示进程从启动到调用clock函数,使用了多少CPU时间。将返回值除以CLOCKS_PER_SEC,就能得到以秒为单位的时间。clock函数声明在time.h头文件中。

 

struct timeval:

        相对来说,time_t的粒度还是比较大,单位是秒。

        Linux还提供了下面另外一个精确度高一些类型strut timeval。

struct timeval {
	time_t      tv_sec;     /* seconds */
	suseconds_t tv_usec;    /* microseconds 微秒*/
};

        成员tv_usec表示的是微秒,1秒 = 1 000毫秒 = 1 000 000微秒。

        一般是在函数gettimeofday函数中使用到这个时间类型。

#include<syt/time.h>
	int gettimeofday(struct timeval *tv, struct timezone *tz);//第二个参数一般为NULL


        像time函数语言,它也返回一个从1970-01-01 00:00:00 UTC(即Epoch时间)到现在流逝的时间,当然这个时间也就是系统时间,为UTC时间不是当地时间。也可以把struct timeval当作现在的时间,将成员tv_sec用上面的localtime转换即可。

        Linux还定义了一系列用于struct  timeval的操作函数。比如相加减,清空,比较。

#include <sys/time.h>
void timeradd(struct timeval *a, struct timeval *b,
			 struct timeval *res);//res = a + b

void timersub(struct timeval *a, struct timeval *b,
			 struct timeval *res);//res = a - b

void timerclear(struct timeval *tvp);

int timerisset(struct timeval *tvp);

int timercmp(struct timeval *a, struct timeval *b, CMP);

        参数CMP就是我们平常用的比较符号<、>=、!=等等。

 

        有一点要注意的是,因为gettimeofday获取的是系统的时间。因为用户是可以手动修改这个系统时间的。所以gettimeofday获取的时间可能是错误的时间。

        如果程序想在两个不同的时刻分别获取系统,然后计算时间差。那么gettimeofday函数不是最佳选择。原因就是用户可以修改系统时间。此时应该使用monotonic时间。monotonic时间是boot启动后到现在的时间,没人能修改它。这个monotonic时间下面会讲解。



struct timespec:

struct timespec {
	time_t   tv_sec;        /* seconds */
	long     tv_nsec;       /* nanoseconds 纳秒*/
};

        它能提供的时间精确度是纳秒。当然,实际上硬件是不一定支持这个精确度的。 有三个与之相关的函数。

//glibc2.17之前的版本在链接时需加上-lrt
#include <time.h>
int clock_getres(clockid_t clk_id, struct timespec *res);
int clock_gettime(clockid_t clk_id, struct timespec *tp);
int clock_settime(clockid_t clk_id, const struct timespec *tp);

        可以用$ldd --version命令查看glibc的版本,uname -r命令查看Linux内核版本。

 

        参数clk_id表示时钟类型,Linux提供下面这些时钟类型。


  • CLOCK_REALTIME: 系统范围的实时时钟。系统范围是指系统的所有用户所有程序都使用。实时时钟是指系统现在的时间(就像Windows右下角的那个时间),这和gettimeofday函数获取的系统时间是相同的。系统时间是可以修改的,所以可以使用clock_settime(CLOCK_REALTIME)修改系统的时间
  • CLOCK_REALTIME_COARSE: 一个更快但时间粒度更大(即时间精确度没那么高)的CLOCK_REALTIME。这个函数是Linux系统特有的,在2.6.32内核版本中首次出现
  • CLOCK_MONOTONIC:monotonic时间。monotonic是单调的意思,也就是说它只会单调递增,不能被人手动修改。POSIX只是说明它是一个单调时间,并没有指定从什么时候开始算起的单调时间。所以有些系统取了Epoch时间,而有些系统(比如Linux)就取boot启动的时间。但也并不影响它的本身意义
  • CLOCK_MONOTONIC_COARSE:一个更快但时间粒度更大(即时间精确度没那么高)的CLOCK_MONOTONIC。这个函数是Linux系统特有的,在2.6.32内核版本中首次出现
  • CLOCK_BOOTTIME: 同CLOCK_MONOTONIC一样,只是当系统被挂起时,一样会计时(CLOCK_MONOTONIC不会)
  • CLOCK_PROCESS_CPUTIME_ID: 进程使用了多少CPU时间。该进程的所有线程所使用的CPU时间都会被统计进来
  • CLOCK_THREAD_CPUTIME_ID: 线程使用了多少CPU时间


        clock_getres函数是用来获取对应时钟类型能够提供的时间精确度,res参数保存其精确度。在设置的时候,设置的时间值也应该是这个精确度的倍数。后面的休眠函数有些也会使用到上面这些时钟类型,休眠的时间也应该是精确度的倍数,否则由休眠函数截断取倍数。比如nanosleep函数。

 

        函数clock_gettime是用来获取对应时钟的时间。函数clock_settime则是用来设置对应时钟的时间。有些时钟是不能被设置的。




休眠函数:

        Linux提供了不同时间精确度的休眠函数。这些函数有些是在Linux高版本才出现的,有些是非线程安全的。下面就详细说明每一个休眠函数。


sleep:

#include <unistd.h>
unsigned int sleep(unsigned int seconds);

        从sleep的参数名称可以看到,该函数的休眠时间单位是秒。由于这个休眠函数可能会被外界的信号所打断,所以其有一个返回值,用来指明余下的休眠时间。如果没有被信号打断,而休眠了参数锁指定的时间,那么将返回0。

        由于sleep函数可能是利用信号SIGALRM实现的,所以不应该在使用sleep函数的同时使用alarm函数。其实在《UNIX环境高级编程》里面,也看到书中有一个例子是怎么实现sleep函数,其中用到的方法就是alarm。

        明显,如果sleep是用SIGALRM实现的话,那么就肯定不是线程安全的。

        要注意的是,在Windows中提供了一个Sleep函数(S是大写的),它的时间单位是毫秒。


usleep:

#include <unistd.h>
int usleep(useconds_t usec);//微秒

        usleep休眠函数的时间粒度比较小,是微秒,足够了。并且该函数是线程安全的。

        当这个休眠函数不被打断地休眠了指定的时间,将返回0。如果被信号打断了,将返回-1,并且将errno设置为EINTR。如果指定的参数不小于1000000也将返回-1,它认为休眠时间太长了,此时errno被设置为EINVAL。

        如果要使用这个函数,那么glibc的版本要不小于2.12。可以用命令$ldd --version查看glibc的版本。


nanosleep:

#include <time.h>
int nanosleep(const struct timespec *req, struct timespec *rem);//纳秒

        nanosleep函数能够提供纳秒级的休眠时间。这是相当不错的。参数req指明要休眠的时间。如果成功休眠了指定的时间,将返回0。

        如果休眠被一个信号给打断了,那么将返回-1,errno被赋值为EINTR。此时如果参数rem不为NULL的话,rem将被赋值成余下的休眠时间。有了rem,即使被信号打断,还是可以继续休眠,直到一开始指定的休眠时间。虽然这种方法理论上是可行,不过实际上可能出现时间漂移。比如说,你要休眠30ms,过了10ms后,被一个信号给打断了。此时rem将得到20ms的剩余值。如果CPU执行信号处理函数用了10ms,接着再休眠rem指明的时间。这样就出现时间漂移,一共休眠了40ms。可以用clock_nanosleep避免这个问题,因为它可以使用绝对时间。

        req的tv_nsec 成员的值范围得是0到999999999。如果是其他值,该函数直接返回-1,errno被设置为EINVAL。

 

        POSIX.1规定,nanosleep是使用CLOCK_REALTIME时钟来检测时间的(即检测是否超时)。然而Linux却是使用CLOCK_MONOTONIC时钟。看上去Linux的做法是明智的,因为前面已经说过用户是可以通过调用clock_settime函数修改CLOCK_REALTIME时钟的。不过,其实POSIX.1也规定了修改CLOCK_REALTIME时钟并不会影响到nanosleep函数的使用。明显要做到这一点,代码会复杂一些。使用CLOCK_MONOTONIC时钟就不用考虑这个问题。


clock_nanosleep:

//glibc2.17之前的版本在链接时需加上-lrt
#include <time.h>
int clock_nanosleep(clockid_t clock_id, int flags,
				   const struct timespec *request,
				   struct timespec *remain);

        参数clock_id指明该函数使用哪个时钟检测有没有睡够。有CLOCK_REALTIME、 CLOCK_MONOTONIC 、CLOCK_PROCESS_CPUTIME_ID三种可选时钟。上面已经对这些时间进行了讲解这里就不多说了。

        参数flags指明用的是不是绝对时间。如果该值为0,则使用的是一个时间段(即休眠的时长)。如果该参数为设置为TIMER_ABSTIME,那么就是使用绝对时间。

        参数request指明休眠时间。有参数flags指明这是一个时间段还是绝对时间。

        参数remain的作用和前面nanosleep函数的rem参数一样。当flags指明request是一个时间段,并且本函数被信号打断时,remain将得到余下的休眠时间。这个参数可以为NULL。

 

        如果flags指定使用绝对时间,并且request指明的时间小于或者等于当前时间,那么clock_nanosleep函数将马上返回,不会进入休眠。

 

        当clock_nanosleep成功休眠了指定的时间,将返回0。否则返回错误值,不设置errno变量。这点和其他的休眠函数不同。有下面这些错误值。

        FAULT: request或者remain指向一个非法地址(即野指针)

        EINTR:本函数被信号函数打断了

        EINVAL:request的tv_nsec成员的范围不是在0到999999999,即它是一个非法值。当clock_id不是去上面说到的那三个值时,也将返回EINVAL。要注意:clock_nanosleep并不支持CLOCK_THREAD_CPUTIME_ID。

      

        该函数要注意的一些问题:因为该函数可以使用CLOCK_REALTIME时钟并且该时钟可以被手动修改。这可能会影响clock_nanosleep函数。首先,如果flags指明的是一个时间段,那么clock_nanosleep和nanosleep函数一样,没有影响。

        如果用户修改了CLOCK_REALTIME时钟的值,必然会对正在利用该时钟进行睡眠的clock_nanosleep产生影响。

        该函数的使用,需要Linux内核版本不小于2.6,glibc版本不小于2.1



        除了上面正规的休眠函数外,还可以利用其他的函数来实现休眠。


select:

#include <sys/select.h>
#include <sys/types.h>
int select(int nfds, fd_set *readfds, fd_set *writefds,
           fd_set *exceptfds, struct timeval *timeout);

        select函数的最后一个参数就是一个时间值。当然它是一个时间段,不是绝对时间。当我们需要将select用作一个休眠函数时,直接把前面四个参数设置为0即可。

        如果休眠了指定的时间,该函数将返回0。如果中途被信号打断,那么将返回-1,errno被设置为EINTR。不同于其他的休眠函数,此时并没有一个可移植的方法知道剩余的休眠时间。虽然部分的Linux会修改timeout参数,得到剩余的休眠时间。



poll:

#include <poll.h>
int poll(struct pollfd *fds, nfds_t nfds, int timeout);

        将前面的两个参数设为0,poll就成了一个休眠函数。参数timeout指定的休眠时间也是一个时间段,并且其时间单位是毫秒。

        如果休眠了指定的时间,该函数返回0。如果中途被信号打断了,那么返回-1,errno被设置为EINTR。



休眠时间精确度:

        由上面列出的一些休眠函数可以知道,Linux提供了各个时间精度的休眠函数:sleep(秒级)、poll(毫秒级)、usleep(微秒级)、nanosleep(纳秒级)。




休眠函数普遍存在的问题:

        休眠函数是有一个问题,那就是不能真正准确休眠指定的时间。主要原因有二个。

  1. 系统提供的时间的精确度不够。比如,系统只能提供10ms的精确度,你却想休眠15ms。此时系统只能把真正休眠时间设置为10ms或者20ms。一般是向上取,即取20ms
  2. CPU调度问题。虽然线程的休眠时间到了,要唤醒了。但此时CPU还在忙着其他事,没有空来唤醒休眠线程。那么休眠线程真正休眠的时间也将是不准确的

参考:

2017-01-04 11:24:45 u011068702 阅读数 4518

 今天在vim 写C语言的时候

 代码我已经导入了#include<math.h>

但是当我调用ads()函数的时候出现了下面错误


解决办法:

把abs函数改写成fabs函数就行,然后去网上找原因,发现fabs是求浮点数的,ads求整形的,以后在linux上就用fabs函数就可以了


2019-02-01 00:50:53 subfate 阅读数 241

某日,网友吃泡面不加开水加我好友,问了一个关于abs函数的问题。在keil中,使用abs计算浮点数的绝对值是没问题的,同样的代码,放到gcc交叉编译器中,却得不到预期结果。趁夜深人静,看了些资料,帮网友解决了问题。
在Linux上执行man abs查看帮助信息,如下:

ABS(3)                                      Linux Programmer's Manual   

NAME
       abs, labs, llabs, imaxabs - compute the absolute value of an integer

SYNOPSIS
       #include <stdlib.h>

       int abs(int j);
       long int labs(long int j);
       long long int llabs(long long int j);

可以看到,abs只针对整数类型求绝对值,不是浮点数。对于浮点数,要使用fabs函数。
下面是man fabs信息:

man fabs
FABS(3)                                     Linux Programmer's Manual    

NAME
       fabs, fabsf, fabsl - absolute value of floating-point number

SYNOPSIS
       #include <math.h>

       double fabs(double x);
       float fabsf(float x);
       long double fabsl(long double x);

可以看到fabs针对double类型,而fabsf针对float类型。不同类型,是不能混用的。

了解原因了,解决问题就容易了:将abs使用fabs替换即可。

后来网友反馈,gcc交叉编译后,得到了预期结果。

李迟 2019.2.1 凌晨 睡前

LinuxC函数

阅读数 0

Linux--C函数

阅读数 380