ubuntu 库函数(ubuntu命令大全)
Ubuntu静态库怎么使用
-供参考
linux静态库的生成与使用
1、windows系统包括静态链接库(*.lib文件)和动态链接库(*.dll文件)。
2、linux通常把库文件存放在/usr/lib或/lib目录下。
linux库文件名:前缀lib、库名和后缀3部分组成,其中动态链接库以.so作为后缀,静态链接库通常以.a作为后缀。
区别:
静态链接库的代码在编译时就拷贝到应用程序中,这样的优点是节省编译时间动态库是程序在开始运行后调用库函数时才被载入。
静态库的创建和使用
1、在一个头文件中声明静态库所导出的函数。
2、在一个源文件中实现静态库所导出的函数。
3、编译源文件,生成可执行代码(.o文件)
4、将可执行代码所在的目标文件加入到某个静态库中,并将静态库拷贝到系统默认的存放文件的目录下。
例如:mylib.h声明函数, mylib.c实现函数
1、编译mylib.c生成目标文件:gcc-o mylib.o-c mylib.c
2、将目标文件加入到静态库中:ar rcs libmylib.a mylib.o
3、将静态库copy到linux的库目录(/usr/lib或者/lib)下:
cp libmylib.a/usr/lib/libmylib.a
4、在调用库函数的文件中添加#include"mylib.h"这样就可调用静态库中函数
5、使用静态库编译:gcc-o main main.c-l mylib
注意:编译时无需带上前缀和后缀。这就是为什么在使用libxml2时librareis(-l)设置为:xml2
-梁兆铃
linux下编写c++,include的那些头文件在什么地方
C/C++程序在linux下被编译和连接时,GCC/G++会查找系统默认的include和link的路径,以及自己在编译命令中指定的路径。
1、#include<stdio.h>,直接到系统指定目录去查找头文件。
系统默认路径为:/usr/include,/usr/local/include,/usr/lib/gcc-lib/i386-Linux/2.95.2/include(gcc库文件的路径,各个系统不一致)
2、#include"stidio.h",会先到当前目录查找头文件,如果没找到在到系统指定目录查找。
3、gcc编译时查找头文件,按照以下路径顺序查找:
gcc编译时,可以设置-I选项以指定头文件的搜索路径,如果指定多个路径,则按照顺序依次查找。比如,gcc-I/usr/local/include/node a.c
gcc会查找环境变量C_INCLUDE_PATH,CPLUS_INCLUDE_PATH中指定的路径。
扩展资料:
应用程序代码编译过程:
编译器根据头文件提供的库函数接口形式,来编译代码,然后生成目标文件;然后,再使用链接器将这个目标文件与系统库链接;最终生成应用程序。代码包含了自己写的内容,还有系统提供好的现成的库函数,整个结合起来才形成一个完整的程序。
库函数的头文件,在编译的时候被使用,而库函数的代码段(库文件),在链接的时候被使用。
example:
应用程序代码在使用一个系统调用的时候,例如printf()函数,需要指定包含的头文件stdio.h;另外,在链接的时候对应的链接libc.a(笔者电脑文件所在目录:/usr/lib/i386-linux-gnu/libc.a)。
总结一下,编写应用程序,需要使用linux系统提供的库函数。具体实现起来,需要头文件和库文件。头文件是需要我们编写应用程序的时候,在源文件开头添加的;而库文件则需要配置编译环境进行指定搜索目录。
ubuntu Linux怎么解决僵尸进程
Linux允许进程查询内核以获得其父进程的 PID,或者其任何子进程的执行状态。例如,进程可以创建一个子进程来执行特定的任务,然后调用诸如 wait()这样的一些库函数检查子进程是否终止。如果子进程已经终止,那么,它的终止代号将告诉父进程这个任务是否已成功地完成。
为了遵循这些设计原则,不允许 Linux内核在进程一终止后就丢弃包含在进程描述符字段中的数据。只有父进程发出了与被终止的进程相关的 wait()类系统调用之后,才允许这样做。这就是引入僵死状态的原因:尽管从技术上来说进程已死,但必须保存它的描述符,直到父进程得到通知。
如果一个进程已经终止,但是它的父进程尚未调用 wait()或 waitpid()对它进行清理,这时的进程状态称为僵死状态,处于僵死状态的进程称为僵尸进程(zombie process)。任何进程在刚终止时都是僵尸进程,正常情况下,僵尸进程都立刻被父进程清理了。
僵尸进程是如何产生的
在UNIX系统中,一个进程结束了,但是他的父进程没有等待(调用wait/ waitpid)他,那么他将变成一个僵尸进程。通过ps命令查看其带有defunct的标志。僵尸进程是一个早已死亡的进程,但在进程表(processs table)中仍占了一个位置(slot)。
但是如果该进程的父进程已经先结束了,那么该进程就不会变成僵尸进程。因为每个进程结束的时候,系统都会扫描当前系统中所运行的所有进程,看看有没有哪个进程是刚刚结束的这个进程的子进程,如果是的话,就由Init进程来接管他,成为他的父进程,从而保证每个进程都会有一个父进程。而Init进程会自动 wait其子进程,因此被Init接管的所有进程都不会变成僵尸进程。
为了观察到僵尸进程,我们自己写一个不正常的程序,父进程 fork出子进程,子进程终止,而父进程既不终止也不调用 wait清理子进程:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
intmain(void)
{
inti= 100;
pid_t pid=fork();
if(pid< 0)
{
perror("fork failed.");
exit(1);
}
if(pid> 0)
{
printf("This is the parent process. My PID is%d.\n", getpid());
for(; i> 0; i--)
{
sleep(1);
}
}
elseif(pid== 0)
{
printf("This is the child process. My PID is:%d. My PPID is:%d.\n", getpid(), getppid());
}
return0;
}
把上面的代码保存到文件 zomprocdemo.c文件中,并执行下面的命令编译:
?
1
$ gcc zomprocdemo.c-o zomprocdemo
然后运行编译出来的 zomprocdemo程序:
?
1
$./zomprocdemo
请点击输入图片描述
此时子进程已经退出,但是父进程没有退出也没有通过 wait()调用处理子进程。我们使用 ps命令查看进程的状态:
请点击输入图片描述
上图红框中的大写字母"Z"说明 PID为 112712的进程此时处于僵死的状态。
让我们接着往下看!在结束 sleep后父进程退出。当父进程退出后,子进程会变成孤儿进程,此时它会被一个管理进程收养。在不同的系统中,这个管理进程不太一样,早期一般是 init进程,Ubuntu上是 upstart,还有近来的 Systemd。但是它们都完成相同的任务,就是 wiat()这些孤儿进程,并最终释放它们占用的系统进程表中的资源。这样,这些已经僵死的孤儿进程就彻底的被清除了。
僵尸进程的危害
在进程退出的时候,内核释放该进程所有的资源,包括打开的文件,占用的内存等。但是仍然为其保留一定的信息(包括进程号 PID,退出状态 the termination status of the process,运行时间 the amount of CPU time taken by the process等)。直到父进程通过 wait/ waitpid来取时才释放。
如果进程不调用 wait/ waitpid的话,那么保留的那段信息就不会释放,其进程号就会一直被占用,但是系统所能使用的进程号是有限的,如果大量的产生僵死进程,将因为没有可用的进程号而导致系统不能产生新的进程。
如何处理僵尸进程
僵尸进程的产生是因为父进程没有 wait()子进程。所以如果我们自己写程序的话一定要在父进程中通过 wait()来避免僵尸进程的产生。
当系统中出现了僵尸进程时,我们是无法通过 kill命令把它清除掉的。但是我们可以杀死它的父进程,让它变成孤儿进程,并进一步被系统中管理孤儿进程的进程收养并清理。
下面的 demo中,父进程通过 wait()等待子进程结束:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include<sys/types.h>
#include<sys/wait.h>
#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
intmain(void)
{
pid_t pid;
pid= fork();
if(pid< 0)
{
perror("fork failed");
exit(1);
}
if(pid== 0){
inti;
for(i= 3; i> 0; i--)
{
printf("This is the child\n");
sleep(1);
}
// exit with code 3 for test.
exit(3);
}
else
{
intstat_val;
wait(&stat_val);
if(WIFEXITED(stat_val))
{
printf("Child exited with code%d\n", WEXITSTATUS(stat_val));
}
}
return0;
}
demo中父进程不仅等待子进程结束,还通过 WEXITSTATUS宏取到了子进程的 exit code。