三星笔试题

本文详细讲解了C语言中库函数atoi的实现原理,强调了处理字符串前导空格和符号的重要性。接着探讨了C++中static关键字的三种用法:局部静态变量、外部静态变量/函数和静态数据成员/成员函数。特别是静态成员函数和静态数据成员在多线程环境和对象计数中的应用,以及它们的局限性,例如不可重入性和内存共享风险。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.B类如何调用A类中的变量
有几个前提条件:
1.被引用的变量所在类必须被完整地定义,而不是只有前向声明(例如只是一行class A;);
2.被引用的变量必须是引用处可访问的。也就是说,以下条件至少满足其中之一:
2.1.访问变量的语句所在的类被声明为被访问的变量所在类的友元类;
2.2.访问变量的语句所在的函数被声明为被访问变量所在类的友元函数;
2.3.被访问变量被public修饰,且访问变量的语句所在的类不是被访问变量所在的类的private继承派生类;
2.4.被访问变量被protected修饰,且访问变量的语句所在的类是被访问变量所在的类的public继承派生类;
2.5.访问变量的语句所在的类定义在被访问变量所在的类的内部。
现在假设满足以上前提条件的B类的某个成员函数或成员初始化的语句要引用A类的成员m,那么
1.当m是A类的静态成员时,可以通过A::m引用;
2.当m是A类的非静态成员,且对象a是类A的实例时,可以通过a.m引用。

2.库函数atoi c语言实现

库函数原型:

#inclue <stdlib.h>

int atoi(const char *nptr);

用法:将字符串里的数字字符转化为整形数,返回整形值。

注意:转化时跳过前面的空格字符,直到遇上数字或正负符号才开始做转换,而再遇到非数字或字符串结束符号时('/0')才结束转换,并将结果返回

例:

#include <stdio.h> #include <stdlib.h>

不调用库函数用C语言实现atoi函数的功能:

#include <stdio.h> #include <stdlib.h>

int my_atoi(const char *str);

int my_atoi(const char *str) {     int value = 0;     int flag = 1; //判断符号

    while (*str == ' ')  //跳过字符串前面的空格     {         str++;     }

    if (*str == '-')  //第一个字符若是‘-’,说明可能是负数     {         flag = 0;         str++;     }     else if (*str == '+') //第一个字符若是‘+’,说明可能是正数     {         flag = 1;         str++;     }//第一个字符若不是‘+’‘-’也不是数字字符,直接返回0     else if (*str >= '9' || *str <= '0')      {         return 0;         }

    //当遇到非数字字符或遇到‘/0’时,结束转化     while (*str != '/0' && *str <= '9' && *str >= '0')     {         value = value * 10 + *str - '0'; //将数字字符转为对应的整形数         str++;     }

    if (flag == 0) //负数的情况     {         value = -value;     }

    return value; }

3.虚函数 纯虚函数,抽象类

1.虚函数 1.1虚函数的作用 虚函数的作用是允许在派生类中重新定义与基类同名的函数,并且可以通过基类指针或引用来访问基类和派生类中的同名函数。 本来,基类指针是指向基类对象的,如果用它指向派生类对象,则进行指针类型转换,将派生类对象的指针先转换为基类指针,所以基类指针指向的是派生类对象中的基类部分。在程序修改前,是无法通过基类指针去调用派生类对象中的成员函数的。 虚函数突破这一限制,在派生类的基类部分中,派生类的虚函数取代了基类原来的虚函数,因此在使用基类指针指向派生类对象后,调用虚函数时就调用了派生类的虚函数。 1.2虚函数的使用方法 【1】在基类用virtual声明成员函数为虚函数。这样就可以在派生类中重新定义此函数,为它赋予新的功能,并能方便地被调用 【2】在派生类中重新定义此函数,要求函数名、函数(返回)类型、函数参数个数和类型与基函数的虚函数相同。如果在派生类中没有对基类的虚函数重定义,则派生类简单地继承直接基类的虚函数。 有一种情况例外,在这种情况下派生类与基类的成员函数返回类型不同,但仍起到虚函数的作用。即基类虚函数返回一个基类指针或基类引用,而子类的虚函数返回一个子类的指针或子类的引用。   【3】C++规定,当一个成员函数被声明为虚函数后,其派生类中的同名函数(符合2中定义的函数)都自动成为虚函数。   【4】定义一个指向基类对象的指针变量,并使其指向同一类族中的某个对象。通过该指针变量调用此函数,此时调用的就是指针变量指向的对象的同名函数。 1.3声明虚函数的限制 【1】只能用virtual声明类的成员函数,使它成为虚函数,而不能将类外的普通函数声明为虚函数。 【2】一个成员函数被声明为虚函数后,在同一类族中的类就不能再定义一个非virtual的但与该虚函数具有相同参数(个数与类型)和函数返回值类型的同名函数。 【3】静态成员函数不能是虚函数,因为静态成员函数不受限于某个对象。 【4】inline函数不能是虚函数,因为inline函数是不能在运行中动态确定其位置的。即使虚函数在类的内部定义,编译时,仍将其视为非inline的。 【5】使用虚函数,系统要有一定的空间开销。当一个类带有虚函数时,编译器会为该类构造一个虚函数表(virtual function tanle,vtable),它是一个指针数组,存放每个虚函数的入口地址。 2.虚析构函数 Time destructor 从结果可以看出,执行的还是基类的析构函数,而程序的本意是希望执行派生类的析构函数。此时将基类的析构函数声明为虚析构函数, 如果将基类的析构函数声明为虚函数,由该基类所派生的所有派生类的析构函数也自动成为虚函数。 把基类的析构函数声明为虚函数的好处是,如果程序中delete一个对象,而delete运算符的操作对象是指向派生类对象的基类指针,则系统会调用相应类的析构函数。 构造函数不能声明为虚函数。 3.纯虚函数 virtual void show()=0;//纯虚函数 这里将show()声明为纯虚函数(pure virtual function)。纯虚函数是在声明虚函数时被“初始化”为0的虚函数。 声明纯虚函数的一般形式为, virtual 函数类型 函数名(参数列表)=0; 纯虚函数没有函数体;最后的“=0”并不代表函数返回值为0,它只起形式上的作用,告诉编译器“这是纯虚函数”;这个一个声明语句,最后有分号。 声明纯虚函数是告诉编译器,“在这里声明了一个虚函数,留待派生类中定义”。在派生类中对此函数提供了定义后,它才能具备函数的功能,可以被调用。 纯虚函数的作用是在基类中为其派生类保留了一个函数的名字,以便派生类根据需要对它进行定义。 如果在一个类中声明了纯虚函数,而在其派生类中没有对该函数定义,则该函数在派生类中仍为纯虚函数。 4.抽象类 将不用来定义对象而只作为一种基本类型用作继承的类,称为抽象类(abstract class),由于它常用作基类,通常称为抽象基类。凡是包含纯虚函数的类都是抽象类。 如果在派生类中没有对所有的纯虚函数进行定义,则此派生类仍然是抽象类,不能用来定义对象。 可以定义指向抽象类数据的指针变量。当派生类成为具体类后,就可以用这个指针指向派生类对象,然后通过该指针调用虚函数。 4.const的作用

     const是C语言的一种关键字,起受保护,防止以外的变动的作用!可以修饰变量,参数,返回值,甚至函数体。const可以提高程序的健壮性,你只管用到你想用的任何地方。 (一)const修饰参数。const只能修饰输入参数。    1、如果输入参数是指针型的,用const修饰可以防止指针被意外修改。    2、如果参数采用值传递的方式,无需const,因为函数自动产生临时变量复制该参数。    3、非内部数据类型的参数,需要临时对象复制参数,而临时对象的构造,析构,复制较为费时,因此建议采用前加const的引用方式传递非内部数据类型。而内部数据类型无需引用传递。 (二)const修饰函数返回值。    1、函数返回const指针,表示该指针不能被改动,只能把该指针赋给const修饰的同类型指针变量。    2、函数返回值为值传递,函数会把返回值赋给外部临时变量,用const无意义!不管是内部还是非内部数据类型。    3、函数采用引用方式返回的场合不多,只出现在类的赋值函数中,目的是为了实现链式表达。 (三)const+成员函数。任何不修改数据成员的函数都应该声明为const类型,如果const成员函数修改了数据成员或者调用了其他函数修改数据成员,编译器都将报错!

5.static的作用

static关键字是C, C++中都存在的关键字, 它主要有三种使用方式, 其中前两种在C/C++语言中使用, 第三种只在C++中使用(C,C++中具体细微操作不尽相同, 本文以C++为准). (1)局部静态变量 (2)外部静态变量/函数 (3)静态数据成员/成员函数 下面就这三种使用方式及注意事项分别说明

一、局部静态变量 在C/C++中, 局部变量按照存储形式可分为三种auto, static, register (<C语言程序设计(第二版)>谭浩强, 第174-175页) 与auto类型(普通)局部变量相比, static局部变量有三点不同 1. 存储空间分配不同 auto类型分配在栈上, 属于动态存储类别, 占动态存储区空间, 函数调用结束后自动释放, 而static分配在静态存储区, 在程序整个运行期间都不释放. 两者之间的作用域相同, 但生存期不同. 2. static局部变量在所处模块在初次运行时进行初始化工作, 且只操作一次 3. 对于局部静态变量, 如果不赋初值, 编译期会自动赋初值0或空字符, 而auto类型的初值是不确定的. (对于C++中的class对象例外, class的对象实例如果不初始化, 则会自动调用默认构造函数, 不管是否是static类型)

特点: static局部变量的”记忆性”与生存期的”全局性” 所谓”记忆性”是指在两次函数调用时, 在第二次调用进入时, 能保持第一次调用退出时的值. 示例程序一 #include <iostream>

using namespace std;

void staticLocalVar() {  static int a = 0; // 运行期时初始化一次, 下次再调用时, 不进行初始化工作  cout<<"a="<<a<<endl;  ++a; }

int main() {  staticLocalVar(); // 第一次调用, 输出a=0  staticLocalVar(); // 第二次调用, 记忆了第一次退出时的值, 输出a=1  return 0; }

应用:  利用”记忆性”, 记录函数调用的次数(示例程序一)    利用生存期的”全局性”, 改善”return a pointer / reference to a local object”的问题. Local object的问题在于退出函数, 生存期即结束,. 利用static的作用, 延长变量的生存期. 示例程序二: // IP address to string format // Used in Ethernet Frame and IP Header analysis const char * IpToStr(UINT32 IpAddr) {  static char strBuff[16]; // static局部变量, 用于返回地址有效  const unsigned char *pChIP = (const unsigned char *)&IpAddr;  sprintf(strBuff, "%u.%u.%u.%u",  pChIP[0], pChIP[1], pChIP[2], pChIP[3]);  return strBuff; }

注意事项: 1. “记忆性”, 程序运行很重要的一点就是可重复性, 而static变量的”记忆性”破坏了这种可重复性, 造成不同时刻至运行的结果可能不同. 2. “生存期”全局性和唯一性. 普通的local变量的存储空间分配在stack上, 因此每次调用函数时, 分配的空间都可能不一样, 而static具有全局唯一性的特点, 每次调用时, 都指向同一块内存, 这就造成一个很重要的问题 ---- 不可重入性!!! 这样在多线程程序设计或递归程序设计中, 要特别注意这个问题. (不可重入性的例子可以参见<effective C++ (2nd)>(影印版)第103-105页) 下面针对示例程序二, 分析在多线程情况下的不安全性.(为方便描述, 标上行号) ① const char * IpToStr(UINT32 IpAddr) ② { ③  static char strBuff[16]; // static局部变量, 用于返回地址有效 ④  const unsigned char *pChIP = (const unsigned char *)&IpAddr; ⑤  sprintf(strBuff, "%u.%u.%u.%u",  pChIP[0], pChIP[1], pChIP[2], pChIP[3]); ⑥  return strBuff; ⑦ } 假设现在有两个线程A,B运行期间都需要调用IpToStr()函数, 将32位的IP地址转换成点分10进制的字符串形式. 现A先获得执行机会, 执行IpToStr(), 传入的参数是0x0B090A0A, 顺序执行完应该返回的指针存储区内容是:”10.10.9.11”, 现执行到⑥时, 失去执行权, 调度到B线程执行, B线程传入的参数是0xA8A8A8C0, 执行至⑦, 静态存储区的内容是192.168.168.168. 当再调度到A执行时, 从⑥继续执行, 由于strBuff的全局唯一性, 内容已经被B线程冲掉, 此时返回的将是192.168.168.168字符串, 不再是10.10.9.11字符串.

二、外部静态变量/函数 在C中static有了第二种含义:用来表示不能被其它文件访问的全局变量和函数。, 但为了限制全局变量/函数的作用域, 函数或变量前加static使得函数成为静态函数。但此处“static”的含义不是指存储方式,而是指对函数的作用域仅局限于本文件(所以又称内部函数)。注意此时, 对于外部(全局)变量, 不论是否有static限制, 它的存储区域都是在静态存储区, 生存期都是全局的. 此时的static只是起作用域限制作用, 限定作用域在本模块(文件)内部. 使用内部函数的好处是:不同的人编写不同的函数时,不用担心自己定义的函数,是否会与其它文件中的函数同名。 示例程序三:   //file1.cpp

static int varA; int varB; extern void funA() { …… }

static void funB() { …… }

//file2.cpp

extern int varB; // 使用file1.cpp中定义的全局变量 extern int varA; // 错误! varA是static类型, 无法在其他文件中使用 // 转注:如果将static int varA;放在file1.h里,file2.cpp包含该头文件,那当然是可以使用的 extern vod funA(); // 使用file1.cpp中定义的函数 extern void funB(); // 错误! 无法使用file1.cpp文件中static函数

// 转注:如果将

static void funB();放在file1.h里,file2.cpp包含该头文件,也是不可以使用的,error C2129: 静态函数“void funB()”已声明但未定义

但如果将

static void funB() { …… }实现挪到头文件,就可以使用了

三、静态数据成员/成员函数(C++特有) C++重用了这个关键字,并赋予它与前面不同的第三种含义:表示属于一个类而不是属于此类的任何特定对象的变量和函数. 这是与普通成员函数的最大区别, 也是其应用所在, 比如在对某一个类的对象进行计数时, 计数生成多少个类的实例, 就可以用到静态数据成员. 在这里面, static既不是限定作用域的, 也不是扩展生存期的作用, 而是指示变量/函数在此类中的唯一性. 这也是”属于一个类而不是属于此类的任何特定对象的变量和函数”的含义. 因为它是对整个类来说是唯一的, 因此不可能属于某一个实例对象的. (针对静态数据成员而言, 成员函数不管是否是static, 在内存中只有一个副本, 普通成员函数调用时, 需要传入this指针, static成员函数调用时, 没有this指针. ) 请看示例程序四(<effective c++ (2nd)>(影印版)第59页) class EnemyTarget { public:   EnemyTarget() { ++numTargets; }   EnemyTarget(const EnemyTarget&) { ++numTargets; }   ~EnemyTarget() { --numTargets; }   static size_t numberOfTargets() { return numTargets; }   bool destroy();   // returns success of attempt to destroy EnemyTarget object private:   static size_t numTargets;               // object counter }; // class statics must be defined outside the class; // initialization is to 0 by default size_t EnemyTarget::numTargets;

在这个例子中, 静态数据成员numTargets就是用来计数产生的对象个数的. 另外, 在设计类的多线程操作时, 由于POSIX库下的线程函数pthread_create()要求是全局的, 普通成员函数无法直接做为线程函数, 可以考虑用Static成员函数做线程函数.

static关键字是C, C++中都存在的关键字, 它主要有三种使用方式, 其中前两种在C/C++语言中使用, 第三种只在C++中使用(C,C++中具体细微操作不尽相同, 本文以C++为准). (1)局部静态变量 (2)外部静态变量/函数 (3)静态数据成员/成员函数 下面就这三种使用方式及注意事项分别说明

一、局部静态变量 在C/C++中, 局部变量按照存储形式可分为三种auto, static, register (<C语言程序设计(第二版)>谭浩强, 第174-175页) 与auto类型(普通)局部变量相比, static局部变量有三点不同 1. 存储空间分配不同 auto类型分配在栈上, 属于动态存储类别, 占动态存储区空间, 函数调用结束后自动释放, 而static分配在静态存储区, 在程序整个运行期间都不释放. 两者之间的作用域相同, 但生存期不同. 2. static局部变量在所处模块在初次运行时进行初始化工作, 且只操作一次 3. 对于局部静态变量, 如果不赋初值, 编译期会自动赋初值0或空字符, 而auto类型的初值是不确定的. (对于C++中的class对象例外, class的对象实例如果不初始化, 则会自动调用默认构造函数, 不管是否是static类型)

特点: static局部变量的”记忆性”与生存期的”全局性” 所谓”记忆性”是指在两次函数调用时, 在第二次调用进入时, 能保持第一次调用退出时的值. 示例程序一 #include <iostream>

using namespace std;

void staticLocalVar() {  static int a = 0; // 运行期时初始化一次, 下次再调用时, 不进行初始化工作  cout<<"a="<<a<<endl;  ++a; }

int main() {  staticLocalVar(); // 第一次调用, 输出a=0  staticLocalVar(); // 第二次调用, 记忆了第一次退出时的值, 输出a=1  return 0; }

应用:  利用”记忆性”, 记录函数调用的次数(示例程序一)    利用生存期的”全局性”, 改善”return a pointer / reference to a local object”的问题. Local object的问题在于退出函数, 生存期即结束,. 利用static的作用, 延长变量的生存期. 示例程序二: // IP address to string format // Used in Ethernet Frame and IP Header analysis const char * IpToStr(UINT32 IpAddr) {  static char strBuff[16]; // static局部变量, 用于返回地址有效  const unsigned char *pChIP = (const unsigned char *)&IpAddr;  sprintf(strBuff, "%u.%u.%u.%u",  pChIP[0], pChIP[1], pChIP[2], pChIP[3]);  return strBuff; }

注意事项: 1. “记忆性”, 程序运行很重要的一点就是可重复性, 而static变量的”记忆性”破坏了这种可重复性, 造成不同时刻至运行的结果可能不同. 2. “生存期”全局性和唯一性. 普通的local变量的存储空间分配在stack上, 因此每次调用函数时, 分配的空间都可能不一样, 而static具有全局唯一性的特点, 每次调用时, 都指向同一块内存, 这就造成一个很重要的问题 ---- 不可重入性!!! 这样在多线程程序设计或递归程序设计中, 要特别注意这个问题. (不可重入性的例子可以参见<effective C++ (2nd)>(影印版)第103-105页) 下面针对示例程序二, 分析在多线程情况下的不安全性.(为方便描述, 标上行号) ① const char * IpToStr(UINT32 IpAddr) ② { ③  static char strBuff[16]; // static局部变量, 用于返回地址有效 ④  const unsigned char *pChIP = (const unsigned char *)&IpAddr; ⑤  sprintf(strBuff, "%u.%u.%u.%u",  pChIP[0], pChIP[1], pChIP[2], pChIP[3]); ⑥  return strBuff; ⑦ } 假设现在有两个线程A,B运行期间都需要调用IpToStr()函数, 将32位的IP地址转换成点分10进制的字符串形式. 现A先获得执行机会, 执行IpToStr(), 传入的参数是0x0B090A0A, 顺序执行完应该返回的指针存储区内容是:”10.10.9.11”, 现执行到⑥时, 失去执行权, 调度到B线程执行, B线程传入的参数是0xA8A8A8C0, 执行至⑦, 静态存储区的内容是192.168.168.168. 当再调度到A执行时, 从⑥继续执行, 由于strBuff的全局唯一性, 内容已经被B线程冲掉, 此时返回的将是192.168.168.168字符串, 不再是10.10.9.11字符串.

二、外部静态变量/函数 在C中static有了第二种含义:用来表示不能被其它文件访问的全局变量和函数。, 但为了限制全局变量/函数的作用域, 函数或变量前加static使得函数成为静态函数。但此处“static”的含义不是指存储方式,而是指对函数的作用域仅局限于本文件(所以又称内部函数)。注意此时, 对于外部(全局)变量, 不论是否有static限制, 它的存储区域都是在静态存储区, 生存期都是全局的. 此时的static只是起作用域限制作用, 限定作用域在本模块(文件)内部. 使用内部函数的好处是:不同的人编写不同的函数时,不用担心自己定义的函数,是否会与其它文件中的函数同名。 示例程序三:   //file1.cpp

static int varA; int varB; extern void funA() { …… }

static void funB() { …… }

//file2.cpp

extern int varB; // 使用file1.cpp中定义的全局变量 extern int varA; // 错误! varA是static类型, 无法在其他文件中使用 // 转注:如果将static int varA;放在file1.h里,file2.cpp包含该头文件,那当然是可以使用的 extern vod funA(); // 使用file1.cpp中定义的函数 extern void funB(); // 错误! 无法使用file1.cpp文件中static函数

// 转注:如果将

static void funB();放在file1.h里,file2.cpp包含该头文件,也是不可以使用的,error C2129: 静态函数“void funB()”已声明但未定义

但如果将

static void funB() { …… }实现挪到头文件,就可以使用了

三、静态数据成员/成员函数(C++特有) C++重用了这个关键字,并赋予它与前面不同的第三种含义:表示属于一个类而不是属于此类的任何特定对象的变量和函数. 这是与普通成员函数的最大区别, 也是其应用所在, 比如在对某一个类的对象进行计数时, 计数生成多少个类的实例, 就可以用到静态数据成员. 在这里面, static既不是限定作用域的, 也不是扩展生存期的作用, 而是指示变量/函数在此类中的唯一性. 这也是”属于一个类而不是属于此类的任何特定对象的变量和函数”的含义. 因为它是对整个类来说是唯一的, 因此不可能属于某一个实例对象的. (针对静态数据成员而言, 成员函数不管是否是static, 在内存中只有一个副本, 普通成员函数调用时, 需要传入this指针, static成员函数调用时, 没有this指针. ) 请看示例程序四(<effective c++ (2nd)>(影印版)第59页) class EnemyTarget { public:   EnemyTarget() { ++numTargets; }   EnemyTarget(const EnemyTarget&) { ++numTargets; }   ~EnemyTarget() { --numTargets; }   static size_t numberOfTargets() { return numTargets; }   bool destroy();   // returns success of attempt to destroy EnemyTarget object private:   static size_t numTargets;               // object counter }; // class statics must be defined outside the class; // initialization is to 0 by default size_t EnemyTarget::numTargets;

在这个例子中, 静态数据成员numTargets就是用来计数产生的对象个数的. 另外, 在设计类的多线程操作时, 由于POSIX库下的线程函数pthread_create()要求是全局的, 普通成员函数无法直接做为线程函数, 可以考虑用Static成员函数做线程函数.

6.在Linux中,常见的进程间通信方法包括一下三种:          
# 管道( pipe ):管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。
# 有名管道 (named pipe) : 有名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信。
# 信号量( semophore ) : 信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。
# 消息队列( message queue ) : 消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。
# 信号 ( sinal ) : 信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生。
# 共享内存( shared memory ) :共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。共享内存是最快的 IPC 方式,它是针对其他进程间通信方式运行效率低而专门设计的。它往往与其他通信机制,如信号两,配合使用,来实现进程间的同步和通信。
# 套接字( socket ) : 套解口也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同及其间的进程通信。


7.前言:介绍在Linux下守护进程的创建.
  Linux下守护进程的创建有很多的方法,比如我们可以使用cron,inetd等程序来创建.这里我们介绍在控制终端上有用户来启动的守护程序.这种守护程序不依赖于任何一个终端,不会随着用户的退出而结束.这种程序经常用于网络程序之中.
  将一个程序变为守护程序一般按照下面的步骤.
  调用函数fork,然后父进程推出,这样子进程就变为了后台进程了.同时子进程不成为进程组的组长(组长可能是父进程或者是创建父进程的进程)为第二步系统调用setsid做准备.
  调用setsid创建一个新的会议组,进程成为一个新的会议组的组长.这样这个会议组就没控制终端了.
  添加信号SIGHUP的处理.为后面的会议组长退出作出处理.同时再一次调用fork.然后父进程推出.由于进程组长退出时向所有会议成员发出SIGHUP,所以我忽略这个信号.这样我们的这个进程就没有了控制终端了.
  调用函数chdir将进程的工作目录改到根目录(/).这样我们的程序可以不占用某个可卸载的设备.防止root卸载设备时系统报告设备忙.
  关闭所有的文件描述符,同时重定向3个标准文件描述符.
  下面的程序将创建一个守护程序,这个程序重定向了标准输出,标准输入,和标准错误输出. 每分钟向标准错误输出可用的系统内存页数.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值