[c++]获得系统名称等信息

jackxiang 2007-9-24 14:40 | |
内容:
系统标识
时间与日期
多进程编程


1. 系统标识符
   a.获得有关的系统信息
      #include
      int uname( struct utsname * name);// 用 man uname 查看 struct utsname
   b.获得系统的名称
      #include
      int gethostname( char* name, int namelen ); // 成功返回 0, 否则返回 1
      例子:
     

      #include<iostream>
 #include<unistd.h>
 #include<sys/utsname.h>
 
 using namespace std;
 
 int main(){
  cout<<"-------------- hostname ------------"<<endl;
  char name[ 100 ];
  memset( name, 0x00, sizeof( name ) );
  gethostname( name, sizeof( name ) );
  cout<< name <<endl;
 
  cout<<"-------------- uname ----------------"<<endl;
  struct utsname nm;
  memset( &nm, 0x00, sizeof( nm ) );
  uname( &nm );
  cout<<"sysname ="<< nm.sysname <<endl;
  cout<<"nodename ="<< nm.nodename <<endl;
  cout<<"release ="<< nm.release <<endl;
  cout<<"version ="<< nm.version <<endl;
  cout<<"machine ="<< nm.machine <<endl;
  return 0;
 }
 

 
2. 时间与日期
   4种表示形式:(1)time_t 1970年至今的秒数               (2) struct tm 以结构表示
                         (3) char * 字符串                               (4) formated char*  自定义格式
   (1)-->(2) 转换有函数: localtime() // 本地时间            gmtime() // 格林威治时间
   (2)-->(1) 转换有函数: mktime()
   (1)-->(3) 转换有函数: ctime()
   (2)-->(3) 转换有函数: asctime()
   (2)-->(4) 转换有函数: strftime()
   例子:
   

   #include<iostream>
#include<time.h>
using namespace std;

int main(){
 // time() get kernel time
 cout<<"-----------time_t-----------"<<endl;
 time_t t=0;
 time( &t );
 cout<< t <<endl;
 
 // time_t --> struct tm, localtime(),gmtime()
 // man localtime to see the struct tm
 cout<<"-----------struct tm-----------"<<endl;
 struct tm *p=NULL;
 p=localtime( &t );  
 cout<<"year:"<< p->tm_year+1900 <<endl; // the number of years since 1900
 cout<<"month:"<< p->tm_mon+1 <<endl; // tm_mon ranges 0 to 11
 cout<<"day:"<< p->tm_mday <<endl;
 
 // struct tm --> time_t
 cout<<"-----------mktime-----------"<<endl;
 time_t t1;
 t1=mktime( p );
 cout<< t1 <<endl;
 
 // time_t --> char *
 cout<<"-----------ctime-----------"<<endl;
 cout<< ctime( &t ) <<endl;
 char ct[ 100 ];                        //如果想保持返回值应开辟新空间,不能直接定义指针保存
 memset( ct, 0x00, sizeof( ct ) ); //因为ctime的返回值总是在同一空间,下次调用ctime时就会被更改
 strcpy( ct, ctime( &t ) );
 cout<< ct <<endl;
 
 // struct tm --> char *
 cout<<"-----------asctime-----------"<<endl;
 cout<< asctime( p ) <<endl;
 
 // struct tm --> formated char*
 cout<<"-----------strftime-----------"<<endl;
 char ft[ 100 ];
 memset( ft, 0x00, sizeof( ft ) );
 strftime( ft, sizeof( ft ), "%Y-%m-%d %H:%M:%S", p );
 cout<< ft <<endl;
 return 0;
}


3.system 函数
  #include
  int system( const char * string );
  执行string 所表示的命令,将产生一个新的进程,system为阻塞函数, 新的进程结束后才继续
  例子:
 

  #include<iostream>
#include<stdlib.h>
using namespace std;

int main(){
 cout<<"----------begin---------"<<endl;
 system("ls -l");
 cout<<"----------end-----------"<<endl;
 return 0;
}

// 一个简单的shell
#include<iostream>
#include<unistd.h>
using namespace std;

int main(){
 char cmd[ 100 ];
 memset( cmd, 0x00, sizeof( cmd ) );
 while( 1 ){
  cout<<"[irini@localhost]#";
  cin.getline( cmd,sizeof( cmd ) );
  if( strcmp( cmd,"bye" )==0 ) break;
  system( cmd );
 }
 return 0;
}



4. atexit() 函数
  #include
  int atexit( void (*func) (void) );
  登记exit handler,最多可登记32个,在进程退出时最后登记的先调用,最先登记的最后调用
 
5. exit 与 _exit
   * 进程的退出过程:
   进程做的事: exit handler( atexit注册的), 关闭IO流,如果申请了堆空间就释放
   ------------------------------------------------------------------
   kernel做的事: 销毁进程空间, 删除进程表中的相应项
   *  exit 是正常退出,想做进程的,然后进入kernel处理
      _exit 是异常退出,直接进入kernel
   
   例子:
   

   #include<iostream>
#include<unistd.h>
using namespace std;

void fn1(){
 cout<<"in fn1()..."<<endl;
}
void fn2(){
 cout<<"in fn2()..."<<endl;
}
int main(){
 atexit( fn1 );
 atexit( fn2 );
 cout<<"return from main..."<<endl;
 //exit( 0 );
 _exit( 0 );
}



6. 进程标识符
  #include
  #include
  pid_t getpid(); // 当前进程号
  pid_t getppid(); // 得到父进程号
  例子:
 

  #include<iostream>
#include<sys/types.h>
#include<unistd.h>
using namespace std;

int main(){
 cout<<"pid="<<getpid()<<endl;
 cout<<"ppid="<<getppid()<<endl;
 return 0;
}



7. fork 函数
   * 创建一个新进程,这个进程是父进程的完全拷贝,完全拷贝父进程的进程空间,唯一的区别是fork()的返回值不同
     返回给父进程的是子进程的pid, 返回给子进程的是0        
     
     例子:
     

     #include<iostream>
 #include<sys/types.h>
 #include<unistd.h>
 using namespace std;
 
 int main(){
  pid_t cid=fork();
  if( cid==0 ){
   for( int i=0; i<5; i++ ){
    cout<<"[child] pid="<<getpid()<<" ppid="<<getppid()<<endl;
    sleep( 1 );
   }
   exit( 0 );
  }else if( cid > 0 ){
   for( int i=0; i<5; i++ ){
    cout<<"[father] pid="<<getpid()<<" cid="<<cid<<endl;
    sleep( 1 );
   }
   exit( 0 );
  }else{
   cout<<"error"<<endl;
   exit( -1 );
  }
  return 0;
 }
 

 
  * fork后,父子进程相互独立,如果之前父进程申请了一个堆空间,那之后父子进程中的指针值相同吗?
    通过程序可验证他们是相同的,但指向的空间是不同,因为进程中分配给指针的不是绝对地址,
    是逻辑偏移地址,进程空间中正文段的起始地址是逻辑0
   
  * 如果父进程在子进程之前退出,子进程会被初始化进程(pid=1) 托管
    如果子进程在父进程之前退出,子进程不会被销毁,变为僵死进程 Z状态,等待父进程处理
   
    例子:
   

    #include<iostream>
 #include<sys/types.h>
 #include<unistd.h>
 using namespace std;
 
 void fn(){
  cout<<"in fn()... "<<endl;
 }
 int main(){
  atexit( fn );
  pid_t cid=fork();
  if( cid==0 ){
   for( int i=0; i<5; i++ ){
    cout<<"[child] pid="<<getpid()<<endl;
    sleep( 1 );
   }
   exit( 0 );
  }else if( cid > 0 ){
   cout<<"father exit..."<<endl;
   exit( 0 );
  }else{
   cout<<"error"<<endl;
   exit( -1 );
  }
  return 0;
 }
 

 
8. wait 和 waitpid 函数
   处理结束的子进程,是阻塞函数
   #include
   #include
   pid_t wait( int * statloc );
   pid_t waitpid( pid_t pid, int *static, int option );
   返回值为子进程的pid
   statloc 用于接受终止的子进程的返回状态
   option 通常设为0  
   
   
   例子:
   

   #include<iostream>
#include<sys/types.h>
#include<sys/wait.h>
#include<unistd.h>
using namespace std;

int main(){
 pid_t cid=fork();
 if( cid==0 ){
  sleep( 3 );
  cout<<"[child] pid="<<getpid()<<" ppid="<<getppid()<<endl;
  exit( 0 );
 }else if( cid > 0 ){
  cout<<"[father] pid="<<getpid()<<" cid="<<cid<<endl;
  int statloc=0;
  pid_t id=waitpid( cid, &statloc, 0 );
  cout<<"[child] "<< id <<" exited"<<endl;
  cout<<"exit value is "<< statloc <<endl;
  if( WIFEXITED( statloc ) )
   cout<<"value "<<WEXITSTATUS( statloc )<<endl;
  else  cout<<"signal "<<WTERMSIG( statloc )<<endl;
 }else{
  cout<<"error"<<endl;
  exit( -1 );
 }
 return 0;
}


9. exec 函数
  类似system,建立新的进程,但不新建进程空间,而是把原进程空间清0变成自己的开始执行
  则原进程exec之后的代码不在存在,失效
 
  例子:
  [code]
  #include
#include
using namespace std;

int main(){
 cout<<"-------------begin-----------"<  //execlp( "ls","ls","-l","-a",NULL );   // 第一个参数为要执行的命令文件名,后面的为命令行参数(从0开始都要写,以NULL结束)
 char* argv[]={ "ls","-l","-a",NULL };
 execvp( "ls", argv );
 cout<<"-------------end-------------"<  return 0;
}

作者:jackxiang@向东博客 专注WEB应用 构架之美 --- 构架之美,在于尽态极妍 | 应用之美,在于药到病除
地址:https://jackxiang.com/post/680/
版权所有。转载时必须以链接形式注明作者和原始出处及本声明!


最后编辑: jackxiang 编辑于2007-9-24 14:42
评论列表
发表评论

昵称

网址

电邮

打开HTML 打开UBB 打开表情 隐藏 记住我 [登入] [注册]