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

Linux编程——进程、信号

2008-06-02 00:17 465 查看
半年不接触linux,有些东西变的太陌生了,再回顾一下我的Linux“基础”编程吧
进程
1.得到进程信息的常用函数:
#include<unistd>
#include <sys/types.h>
pid_t getpid(void); //进程ID
pid_t getppid(void);//父进程ID
uid_t getuid(void); //进程所有者的ID
uid_t geteuid(void); //进程有效用户ID,和系统的资源使用有关,涉及到进程的权限
gid_t getgid(void); //组ID
git_t getegid(void);//有效组ID,不知道这两个是干什么的,要用到的时候再说
另一个很有用的函数和结构:
struct passwd {
char *pw_name; /* 登录名称 */
char *pw_passwd; /* 登录口令 */
uid_t pw_uid; /* 用户ID */
gid_t pw_gid; /* 用户组ID */
char *pw_gecos; /* 用户的真名 */
char *pw_dir; /* 用户的目录 */
char *pw_shell; /* 用户的SHELL */
};
#include <pwd.h>
#include <sys/types.h>
struct passwd *getpwuid(uid_t uid);//得到“passwd”
2.创建进程
#include <unistd.h>
pid_t fork();
在创建子进程后,为了区分父进程和子进程,我们必须跟踪fork的返回值.失败返回-1,父进程中返回子进程ID,也就是>0,子进程中返回0.
调用wait或者waitpid系统调用来处理进程间的资源利用冲突。
#include <sys/types.h>;
#include <sys/wait.h>;
pid_t wait(int *stat_loc);
//使父进程阻塞直到一个子进程结束或者是父进程接受到了一个信号.如果没有父进程没有子进程或者他的子进程已经结束了wait回立即返回.成功时(因一个子进程结束)wait将返回子进程的ID,否则返回-1. stat_loc是子进程的退出状态. 子进程调用exit,_exit 或者是return来设置这个值. 为了得到这个值Linux定义了几个宏来测试这个返回值. WIFEXITED:判断子进程退出值是非0 ;WEXITSTATUS:判断子进程的退出值(当子进程退出时非0) ;WIFSIGNALED:子进程由于有没有获得的信号而退出;WTERMSIG:子进程没有获得的信号号(在WIFSIGNALED为真时才有意义).
pid_t waitpid(pid_t pid,int *stat_loc,int options);
// waitpid等待指定的子进程直到子进程返回.如果pid为正值则等待指定的进程(pid).如果为0则等待任何一个组ID和调用者的组ID相同的进程.为-1时等同于wait调用.小于-1时等待任何一个组ID等于pid绝对值的进程程. stat_loc同上. options可以决定父进程的状态.可以取两个值 WNOHANG:父进程立即返回当没有子进程存在时. WUNTACHED:当子进程结束时waitpid返回,但是子进程的退出状态不可得到.
3.调用系统程序:exec()
父进程创建子进程后,子进程一般要执行不同的程序.为了调用系统程序,我们可以使用系统调用exec族调用. #include <unistd.h>;
int execl(const char *path,const char *arg,...);
int execlp(const char *file,const char *arg,...);
int execle(const char *path,const char *arg,...);
int execv(const char *path,char *const argv[]);
int execvp(const char *file,char *const argv[]);
//这五个函数总是见到,总是使用。它们有着不同的功能。
4.进程的终止
信号
1. 产生、发送
有两种可能:硬件、软件。
#include <sys/types.h>;
#include <signal.h>;
#include <unistd.h>;
int kill(pid_t pid,int sig); //向任意进程发送信号
int raise(int sig); //向自己发送信号
unisigned int alarm(unsigned int seconds);//定时发送信号
setitimer //
2. 信号操作
接到信号后要进行相应操作,如若不然将执行系统默认操作。
a、 信号屏蔽
#include <signal.h>;
int sigemptyset(sigset_t *set);
int sigfillset(sigset_t *set);
int sigaddset(sigset_t *set,int signo);
int sigdelset(sigset_t *set,int signo);
int sigismember(sigset_t *set,int signo);
int sigprocmask(int how,const sigset_t *set,sigset_t *oset);
//还是重点记一下sigprocmask函数吧:参数how决定函数的操作方式,有如下几种:
SIG_BLOCK:增加一个信号集合到当前进程的阻塞集合之中.
SIG_UNBLOCK:从当前的阻塞集合之中删除一个信号集合.
SIG_SETMASK:将当前的信号集合设置为信号阻塞集合.
注意:信号屏蔽只是将信号加入到信号阻塞集合之中,并没有丢弃这个信号.一旦信号屏蔽取消了,这个信号就会发生作用.
b.如果我们不想只是简单的屏蔽信号,而是想在信号产生时采取一定的动作,那么就要使用sigaction函数 #include <signal.h>;
int sigaction(int signo,const struct sigaction *act,struct sigaction *oact);
struct sigaction {
void (*sa_handler)(int signo);
void (*sa_sigaction)(int siginfo_t *info,void *act);
sigset_t sa_mask;
int sa_flags;
void (*sa_restore)(void);
} //这个函数的主要操作在于设置act,sa_handler对应着操作函数。
c.pause和sigsuspend
#include <unistd.h>;
#include <signal.h>;
int pause(void); //挂起进程直到一个信号发生
int sigsuspend(const sigset_t *sigmask);
//挂起进程,并且在调用的时候用sigmask取代当前的信号阻塞集合
#include <sigsetjmp>;
int sigsetjmp(sigjmp_buf env,int val);
void siglongjmp(sigjmp_buf env,int val); //类似于goto语句
3. 实例
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: