Linux下进程编程
来源:互联网 发布:闲鱼淘宝介入后谁会赢 编辑:程序博客网 时间:2024/05/18 02:26
Linux下进程编程
写给linux编程的初学者,进程编程是linux编程首先要学习的东西,往后要学习进程之间通讯的一些编程。下面的是进程编程的一些基本函数。
1. 用户标识(UID)和有效用户标识(EUID)
使用getuid函数和geteuid函数来获取当前进程的用户标识和有效用户标识
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main(void){
printf("Current process UID : %ld\n",(long)getuid());
printf("Current porcess EUID : %ld\n",(long)geteuid());
return 0;
}
运行结果:
Current process UID:500
Current process EUID:500
2. fork函数
通过fork函数并判断函数返回值,根据返回值来判断是在父进程还是子进程。
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int main(void){
pid_t pid;
//fork函数如果返回值小于0,表示调用失败
//如果返回值为0,表示处于进程中,如果大于0,表示在父进程中
if((pid=fork())<0){
perror("Cannot create the new process");
return 1;
}else if(pid==0){
printf("In the child process!\n");
return 0;
}else {
printf("In the parent process!\n");
return 0;
}
}
运行结果:
In the child processs!!
In the parent process!!
调用fork函数后,其后代码会被父子进程分别执行。
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int main(void){
fork();
printf("Will be executed twice\n");
return 0;
}
运行结果:
Will be excuted twice
Will be excuted twice
3. vfork函数
首先定义g_var为全局变量, var为局部变量,然后调用fork函数创建子进程,并在子进程对g_var变量和var变量进行修改。子进程在输出这两个变脸值后退出,输出父进程中的这两个变量的取值情况。
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int g_var=0;
int main(void){
pid_t pid;
int var=1;
printf("process id:%ld\n",(long)getpid());
printf("before execute the fork system call, g_var=%d var=%d\n",g_var,var);
if((pid=fork())<0){
perror("Cannot create a new process");
return 1;
}else if(pid==0){
g_var++;
var++;
printf("process id : %ld, g_var=%d var=%d\n",(long)getpid(),g_var,var);
_exit(0);
}
printf("process id : %ld, g_var=%d var=%d\n",(long)getpid(),g_var,var);
return 0;
}
运行结果:
Process id :24437
Before excute the fork system call,g_var=0 var=1
Process id :24438, g_var=1 var=2
Process id :24437, g_var=0 var=1
修改上面的程序,将fork函数的语句进行替换,使用vfork函数,将代码保存并运行
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int g_var=0;
int main(void){
pid_t pid;
int var=1;
printf("process id:%ld\n",(long)getpid());
printf("before execute the fork system call, g_var=%d var=%d\n",g_var,var);
if((pid=vfork())<0){
perror("Cannot create a new process");
return 1;
}else if(pid==0){
g_var++;
var++;
printf("process id : %ld, g_var=%d var=%d\n",(long)getpid(),g_var,var);
_exit(0);
}
printf("process id : %ld, g_var=%d var=%d\n",(long)getpid(),g_var,var);
return 0;
}
运行结果:
Process id :24574
Before excute the fork system call,g_var=0 var=1
Process id :24575, g_var=1 var=2
Process id :24574, g_var=1 var=2
4 exec 函数族
execvp函数支持参数列表,使用参数列表将使程序获得更大的灵活性,程序通过读取agrv中的参数,实现对输入的shell命令的执行。
#include <stdio.h>
#include <unistd.h>
int main(int argc,char* argv[]){
if(argc<2){
printf("Usage: %s path\n",argv[0]);
return 1;
}
execlp("/bin/ls","ls",argv[1],(char*)NULL);
return 0;
}
5 exit函数
使用atexit注册了一个在进程退出时的处理函数,该处理函数只是显示一段文字信息。Main函数退出时将调用exit函数,这样进程就会在退出时自动调用atexit注册的处理函数。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void do_at_exit(void)
{
printf("You can see the output when the program terminates\n");
}
int main(){
int flag;
flag=atexit(do_at_exit);
if (flag != 0) {
printf("Cannot set exit function\n");
return EXIT_FAILURE;
}
exit(EXIT_SUCCESS);
}
6 _exit函数
下面的程序和上面的除了退出函数不同,其他都一样。不同的是使用_exit函数退出时,不会执行atexit中注册的处理函数
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void do_at_exit(void)
{
printf("You can see the output when the program terminates\n");
}
int main(){
int flag;
flag=atexit(do_at_exit);
if (flag != 0) {
printf("Cannot set exit function\n");
return EXIT_FAILURE;
}
_exit(EXIT_SUCCESS);
}
7 kill 函数发送信号
直接用kill函数给进程发送结束信号或是让程序自动退出。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
int main(int argc,char* argv[]){
pid_t pid;
int exit_code;
pid=getpid();
srand((unsigned)pid);
exit_code=(int)(rand() % 256);
sleep(10);
if(atoi(*(argv+1)) % 2){
printf("the child process id:%d receive signal SIGKILL\n",pid);
kill(pid,9);
}else{
printf("the child process id:%d normally exit,exit_code is %0x\n",pid,exit_code);
exit(exit_code);
}
}
下面程序通过fork函数创建子进程,并调用execl函数执行上面的程序。为了方便了解程序运行情况,在父进程中显示了创建的子进程的进程号。在while循环中调用wait函数,跳出条件是wait函数放回值小于0,或wait_pid为-1。这种情况下,所有的子进程都已经完全退出。
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
int main(int argc,char* argv[]){
pid_t pid,wait_pid;
int status;
int i;
if(argc<4){
printf("Usage: %s para1 para2 para3\n",argv[0]);
return 1;
}
for(i=1;i<4;i++)
if((pid=fork())==0)
execl("./p7.14","p7.14",argv[i],NULL);
else
printf("create the child process id: %d\n",pid);
while((wait_pid=wait(&status)) && wait_pid!=-1)
printf("process id:%d exit,exit_code is %0x\n",wait_pid,status);
return 0;
}
8 waitpid函数
使用waitpid等待SIGSTOP,SIGCONT和SIGKILL这3种信号.
#include <stdio.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <unistd.h>
int main(void)
{
pid_t pid,wait_pid;
int status;
pid = fork();
if (pid==-1) {
perror("Cannot create new process");
exit(1);
} else if (pid==0) {
printf("child process id: %ld\n", (long) getpid());
pause();
_exit(0);
} else {
do {
wait_pid=waitpid(pid, &status, WUNTRACED | WCONTINUED);
if (wait_pid == -1) {
perror("cannot using waitpid function");
exit(1);
}
if (WIFEXITED(status))
printf("child process exites, status=%d\n", WEXITSTATUS(status));
if(WIFSIGNALED(status))
printf("child process is killed by signal %d\n", WTERMSIG(status));
if (WIFSTOPPED(status))
printf("child process is stopped by signal %d\n", WSTOPSIG(status));
if (WIFCONTINUED(status))
printf("child process resume running....\n");
} while (!WIFEXITED(status) && !WIFSIGNALED(status));
exit(0);
}
}
9. 僵尸进程
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main (void)
{
pid_t pid;
pid = fork();
if(pid<0){
perror("cannot create new process");
exit(1);
}
if (pid>0)
sleep (60);
else
exit (0);
return 0;
}
- Linux下进程编程
- linux下进程编程综述
- linux下进程优先级编程
- Linux下多进程编程
- 【Linux】Linux 下多进程编程详解
- linux下多进程编程简介
- Linux下的多进程编程
- Linux下的多进程编程
- Linux下的多进程编程
- Linux 下的多进程编程
- Linux下的多进程编程初步
- Linux 下的多进程编程
- Linux下的多进程编程
- Linux 下的多进程编程
- Linux下的多进程编程
- Linux下的多进程编程
- Linux下的多进程编程
- Linux下的多进程编程
- Keil5 J-link V8固件升级
- HDU 2003 - 求绝对值
- php内存溢出
- 为kindeditor添加在线播放视频功能(基于原有flash上传,mp4,flv,flash)
- Android学习笔记——文件路径(/mnt/sdcard/...)、Uri(content://media/external/...)学习
- Linux下进程编程
- 如何利用指针实现冒泡排序,以及指针使用时位置的确定
- Android打开并读取Word文件到html中采用PIO技术
- servlet&jsp经典总结
- HDU 2004 - 成绩转换
- 世界坐标系,本地坐标系,opengl坐标系,屏幕坐标系
- C字符串处理函数
- 游戏数据分析的架构及调优
- leetcode: Path Sum