歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> 關於Linux >> Linux編程:時間與文件及信號的操作

Linux編程:時間與文件及信號的操作

日期:2017/3/3 16:12:24   编辑:關於Linux
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <time.h>
void fun(int x)
{
 printf("hello world!\r\n");
 int i;
 FILE *f=fopen("a.txt","rw+");
 if(f==NULL)
{printf("file error\r\n");
  exit(-1);};
 for(i=0;i<10;i++)
 {
  time_t a=time(NULL);
  printf("%s\r\n",ctime(&a));
  //功 能: 把日期和時間轉換為字符串
  //用 法: char *ctime(const time_t *time);
  fprintf(f,"%s\r\n",ctime(&a));
    
  struct tm *gmt;
  gmt = gmtime(&a);
     printf("%d/%d/%d  %d:%d:%d %d\r\n",gmt->tm_year+1900,gmt->tm_mon+1,gmt->tm_mday ,gmt->tm_hour,gmt->tm_min,gmt->tm_sec,gmt->tm_wday+1);
     fprintf(f,"%d/%d/%d  %d:%d:%d %d\r\n\n",gmt->tm_year+1900,gmt->tm_mon+1,gmt->tm_mday ,gmt->tm_hour,gmt->tm_min,gmt->tm_sec,gmt->tm_wday+1);
  sleep(2);
 }
 fclose(f);
 exit(1);
}
int main()
{
 signal(SIGINT,fun);    
 while(1);
}

表頭文件#include<signal.h>

功 能:設置某一信號的對應動作

函數原型:void (*signal(int signum,void(* handler)(int)))(int);

或者:typedef void(*sig_t) ( int );

sig_t signal(int signum,sig_t handler);

參數說明:

第一個參數signum指明了所要處理的信號類型,它可以取除了SIGKILL和SIGSTOP外的任何一種信號。

第二個參數handler描述了與信號關聯的動作,它可以取以下三種值:

(1)一個無返回值的函數地址

此函數必須在signal()被調用前申明,handler中為這個函數的名字。當接收到一個類型為sig的信號時,就執行handler 所指定的函數。這個函數應有如下形式的定義:

void func(int sig);

sig是傳遞給它的唯一參數。執行了signal()調用後,進程只要接收到類型為sig的信號,不管其正在執行程序的哪一部分,就立即執行func()函數。當func()函數執行結束後,控制權返回進程被中斷的那一點繼續執行。

(2)SIG_IGN

這個符號表示忽略該信號,執行了相應的signal()調用後,進程會忽略類型為sig的信號。

(3)SIG_DFL

這個符號表示恢復系統對信號的默認處理。

函數說明:

signal()會依參數signum 指定的信號編號來設置該信號的處理函數。當指定的信號到達時就會跳轉到參數handler指定的函數執行。當一個信號的信號處理函數執行時,如果進程又接收到了該信號,該信號會自動被儲存而不會中斷信號處理函數的執行,直到信號處理函數執行完畢再重新調用相應的處理函數。但是如果在信號處理函數執行時進程收到了其它類型的信號,該函數的執行就會被中斷。

返回值:返回先前的信號處理函數指針,如果有錯誤則返回SIG_ERR(-1)。

下面的情況可以產生Signal:

按下CTRL+C產生SIGINT

硬件中斷,如除0,非法內存訪問(SIGSEV)等等

Kill函數可以對進程發送Signal

Kill命令。實際上是對Kill函數的一個包裝

軟件中斷。如當Alarm Clock超時(SIGURG),當Reader中止之後又向管道寫數據(SIGPIPE),等等

程序例:

This example installs a signal handler routine for SIGFPE,catches an integer overflow condition, makes an adjustment to AX register, and returns. This example program MAY cause your computer to crash, and will produce runtime errors depending on which memory model is used.

#pragma inline
#include <stdio.h>
#include <signal.h>
void Catcher(int sig, int type, int *reglist)
{
printf("Caught it!\n");
*(reglist + 8) = 3; // make return AX = 3
}
int main(void)
{
signal(SIGFPE, Catcher);
asm mov ax,07FFFH
// AX = 32767
asm inc ax
    
// cause overflow
asm into
// activate handler
The handler set AX to 3 on return. If that hadn't happened,
there would have been another exception when the next 'into'
was executed after the 'dec' instruction.
asm dec ax
// no overflow now
asm into
// doesn't activate
return 0;
}

2 Signals:

Signal

Description

SIGABRT

由調用abort函數產生,進程非正常退出

SIGALRM

用alarm函數設置的timer超時或setitimer函數設置的interval timer超時

SIGBUS

某種特定的硬件異常,通常由內存訪問引起

SIGCANCEL

由Solaris Thread Library內部使用,通常不會使用

SIGCHLD

進程Terminate或Stop的時候,SIGCHLD會發送給它的父進程。缺省情況下該Signal會被忽略

SIGCONT

當被stop的進程恢復運行的時候,自動發送

SIGEMT

和實現相關的硬件異常

SIGFPE

數學相關的異常,如被0除,浮點溢出,等等

SIGFREEZE

Solaris專用,Hiberate或者Suspended時候發送

SIGHUP

發送給具有Terminal的Controlling Process,當terminal被disconnect時候發送

SIGILL

非法指令異常

 

SIGINFO

BSD signal。由Status Key產生,通常是CTRL+T。發送給所有Foreground Group的進程

SIGINT

由Interrupt Key產生,通常是CTRL+C或者DELETE。發送給所有ForeGround Group的進程

SIGIO

異步IO事件

SIGIOT

實現相關的硬件異常,一般對應SIGABRT

SIGKILL

無法處理和忽略。中止某個進程

SIGLWP

由Solaris Thread Libray內部使用

SIGPIPE

在reader中止之後寫Pipe的時候發送

SIGPOLL

當某個事件發送給Pollable Device的時候發送

SIGPROF

Setitimer指定的Profiling Interval Timer所產生

SIGPWR

和系統相關。和UPS相關。

SIGQUIT

輸入Quit Key的時候(CTRL+\)發送給所有Foreground Group的進程

SIGSEGV

非法內存訪問

SIGSTKFLT

Linux專用,數學協處理器的棧異常

SIGSTOP

中止進程。無法處理和忽略。

SIGSYS

非法系統調用

SIGTERM

請求中止進程,kill命令缺省發送

SIGTHAW

Solaris專用,從Suspend恢復時候發送

SIGTRAP

實現相關的硬件異常。一般是調試異常

SIGTSTP

Suspend Key,一般是Ctrl+Z。發送給所有Foreground Group的進程

SIGTTIN

當Background Group的進程嘗試讀取Terminal的時候發送

SIGTTOU

當Background Group的進程嘗試寫Terminal的時候發送

SIGURG

當out-of-band data接收的時候可能發送

SIGUSR1

用戶自定義signal 1

SIGUSR2

用戶自定義signal 2

SIGVTALRM

setitimer函數設置的Virtual Interval Timer超時的時候

SIGWAITING

Solaris Thread Library內部實現專用

SIGWINCH

當Terminal的窗口大小改變的時候,發送給Foreground Group的所有進程

SIGXCPU

當CPU時間限制超時的時候

SIGXFSZ

進程超過文件大小限制

SIGXRES

Solaris專用,進程超過資源限制的時候發送

包含頭文件:time.h

原型:struct tm *gmtime(long *clock);

功能:把日期和時間轉換為格林威治(GMT)時間的函數。將參數timep 所指的time_t 結構中的信息轉換成真實世界所使用的時間日期表示方法,然後將結果由結構tm返回。

結構tm的定義為

struct tm
{
int tm_sec;
int tm_min;
int tm_hour;
int tm_mday;
int tm_mon;
int tm_year;
int tm_wday;
int tm_yday;
int tm_isdst;
};
int tm_sec 代表目前秒數,正常范圍為0-59,但允許至61秒
int tm_min 代表目前分數,范圍0-59
int tm_hour 從午夜算起的時數,范圍為0-23
int tm_mday 目前月份的日數,范圍01-31
int tm_mon 代表目前月份,從一月算起,范圍從0-11
int tm_year 從1900 年算起至今的年數
int tm_wday 一星期的日數,從星期一算起,范圍為0-6
int tm_yday 從今年1月1日算起至今的天數,范圍為0-365
int tm_isdst 日光節約時間的旗標
此函數返回的時間日期未經時區轉換,而是UTC時間。
返回值 返回結構tm代表目前UTC 時間
編輯本段應用舉例
#include "stdio.h"
#include "time.h"
#include "stdlib.h"
int main(void)
{
time_t t;
struct tm *gmt, *area;
tzset();  
t = time(NULL);
area = localtime(&t);
printf("Local time is: %s", asctime(area));
gmt = gmtime(&t);
printf("GMT is: %s", asctime(gmt));
return 0;
}

本文出自 “好好活著” 博客,請務必保留此出處http://wolfword.blog.51cto.com/4892126/1225008

Copyright © Linux教程網 All Rights Reserved