您的位置:首页 > 运维架构 > Linux

Linux进程与线程之二

2015-10-10 10:55 399 查看
                       每日一结

一 字符串分割函数 

char *strtok(char *str, const char *delim);

功能:根据分隔符号来分割字符串 

参数:

@str   第一次:字符串首地址    后面传递:NULL [告诉strtok函数接着上一次后面操作]

@delim 分割字符串 

返回值:

成功返回子串的首地址,结束返回NULL  

(对于这个函数的具体用法,自己man page。在string.c中,还可以看strtok()函数的源代码,有空可以看看它的实现)

二  exec函数族 

e:执行程序的时候,可以给程序传递环境变量 

int execle(const char *path, const char *arg,..., char * const envp[]);

char *envp[] = {"PATH=/home/linux","TEST=HELLO WORD",NULL};

注:对于exec函数族,要学会使用其中的一种,并且明白v , p ,e各自都代表什么意思。并明白什么时候去使用exec函数族中的函数。

(待整理)

 

 

三 回收僵尸态子进程 

 

僵尸态子进程产生的原因 :

一个进程在调用exit命令结束自己的生命的时候,其实它并没有真正的被销毁,而是留下一个称为僵尸进程(Zombie)的数据结构(系统调用exit,它的作用是使进程退出,但也仅仅限于将一个正常的进程变成一个僵尸进程,并不能将其完全销毁)。在Linux进程的状态中,僵尸进程是非常特殊的一种,它已经放弃了几乎所有内存空间,没有任何可执行代码,也不能被调度,仅仅在进程列表中保留一个位置,记载该进程的退出状态等信息供其他进程收集,除此之外,僵尸进程不再占有任何内存空间。它需要它的父进程来为它收尸,如果他的父进程没安装SIGCHLD信号处理函数调用wait或waitpid()等待子进程结束,又没有显是忽略该信号,那么它就一直保持僵尸状态,如果这时父进程结束了,那么init进程自动会接手这个子进程,为它收尸,它还是能被清除的。但是如果父进程是一个循环,不会结束,那么子进程就会一直保持僵尸状态,这就是为什么系统中有时会有很多的僵尸进程。 

 

1.为什么要回收? 

 

僵尸态子进程已经结束,它占用大部分资源已经释放,但是仍然保留PID资源。 

如果僵尸态子进程过多,会导致PID资源耗尽,创建子进程失败。

注:cat /proc/sys/kernel/pid_max可以查看操作系统中pid的个数。

2.pid_t wait(int *status) 

功能:回收僵尸态子进程

参数:

@status  获取进程结束状态 

返回值:

成功返回僵尸态子进程的PID,失败返回-1(没有子进程)

-----------------------------------------------------

特点:

(1)任意子进程进入僵尸态都可以处理 

(2)如果没有子进程进入僵尸态,阻塞调用者 

-----------------------------------------------------

 

3.pid_t waitpid(pid_t pid, int *status, int options);

功能:等待一个特定PID的子进程状态发生改变[R->T ,T->R, R->Z]

参数:

pid  是一个指定子进程的PID 

pid  -1[任意一个子进程]

@status    获取子进程状态 

@options   0:阻塞的方式调用   WNOHANG:非阻塞的方式调用  

返回值:

(1)返回子进程的PID 

(2)返回0 [采用非阻塞方式调用且没有子进程状态发生改变]

(3)-1    [没有它处理的子进程]

(明白wait()和waitpid()函数的区别,并且要知道什么时候去用wait()函数,什么时候去用waitpid()函数)

参考笔记

 





代码分析如下:

 

 

 

四 exit(),_exit(),return 之间的区别 

return   : C语言的关键字,用于一个函数的返回。在main函数中的时候,用于结束一个进程 

exit()   : 是一个系统调用函数,任何地方调用它,都会结束当前进程,并且将缓存的数据进行刷新

_exit()  : 是一个系统调用函数,任何地方调用它,都会结束当前进程,并且不会将缓存的数据进行刷新 

 

 

五 Linux 守护进程 

(1)创建子进程,父进程退出  

(2)在子进程中创建的新会话 [setsid() : 调用者不能是组长进程]

(3)改变进程的工作目录到"/"

(4)重设文件掩码 umask(0) 

(5)关闭不需要的文件描述符号 [0,1,2]   

注:创建完守护进程之后,一定要记得将其杀死,不然它会一直运行,那会占用你很大的磁盘空间。需要用信号将其杀死。

 

六 普通用户运行程序,创建的进程拥有超级用户权限

RUID:标识创建进程的用户

EUID:标识进程的访问权限

SUID:保存EUID 

(注:课下自己查询一下RUID,EUID,SUID,可参考man page和鸟哥私房菜)

-----------------------------------------------------------

如果可执行文件set-id-bit 被设置,运行这个程序创建的进程,其EUID由文件所有者决定

注:自己去弄清楚为什么要设置这一步?

-----------------------------------------------------------

<1>改变文件的所有者为root

sudo  chown  root  可执行文件 

<2>打开set-id-bit 

sudo chmod u+s  可执行文件 

 

注:组长不能创建新会话

 

练习:

写一个守护进程写时间日志 [每次将系统时间写入文件] 

参考代码如下:







参照笔记写其代码分析:

 

 

七 多线程编程     

线程特点:

(1)多个线程共享同一个进程的地址空间 

(2)多个线程参与统一调度 

线程私有资源:

(1)线程ID 

(2)一组寄存器值 

(3)私有栈资源 

...

线程间共享的资源:

(1)整个进程的地址空间 

(2)全局变量 

...

1.创建线程 

int pthread_create(pthread_t *thread, const pthread_attr_t *attr,

           void *(*start_routine) (void *), 

   void *arg

   );

功能:创建一个线程 

 

参数:

@thread              获得线程ID 

@attr                NULL:默认的属性 

@start_routine       线程执行的函数

@arg                 传递给线程执行函数传递参数 

返回值:

成功返回0,失败返回错误码 

注:

I. 在创建线程的时候,老师解压了一个线程库,自己课后百度一下。还有就是这个线程函数:pthread_create()。再一个就是因为这个线程库是第三方库,所以需要在编译时加上  -l库名

II. 对于最后一个参数,对于其数据类型void,看是否可以传其他的数据类型的参数,自己课下去验证一下。(关键还是得弄明白void这个数据类型)

III.主线程和子线程共用哪些资源?以及线程与进程的区别?

 

练习:

1.创建一个线程,传递多个参数个线程函数 

int int_data = 100;

short short_data = 200;

char  char_data = 50;

在这个线程函数中输出这些参数的值 

 

 

 

 

 

 

代码示例如下:





代码分析如下:

 

 

注:I.在线程中,自己查看man page可以知道,传递给函数中的参数只有一个,所以若想传递多个参数,可以打包成结构体,然后再依次访问。

 II.熟悉线程的创建流程,自己课下可以man page一下

 

 

 

晚间任务:

int main()

{

1.用open函数读写方式打开一个文件,文件不存在则创建,文件存在则清空 

2.创建一个子线程,给线程传递的参数是文件描述符号 

子线程:从文件中读取数据,然后输出 

主线程:读取用户输入的字符串,然后写入文件 

 

注意  :如果用户输入的是"quit"字符串,则结束

(这个事情我们在进程中做过一次,回顾一下当时的思路)

return 0;

}

具体代码如下:





代码分析如下:

 

待思考的问题:

I.在switch,case语句中, break;语句不能让其退出,需要用goto语句,关于这一点,课下自己验证其正确性。

II.man一下getpid()函数,getppid()函数,atoi()函数和getenv()函数

III.对照一下自己写的代码和老师写的代码的出入之处并加以改进。

IV.对照着笔记去整理一下这篇文档

 

关注微信公众号获取更多资讯



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: