LinuxC常用系统调用函数

克隆进程-fork()

原型:

__pid_t fork()

头文件:unistd.h

参数:无

返回值:有三种不同的返回值。对于被克隆的进程返回克隆的进程ID。对于克隆的进程返回0。出错返回-1

作用:用于创建一个新进程。直接克隆一个与原进程完全相同的进程,从代码同一位置继续运行。

特性:fork出的进程与原进程是异步并发执行的。

pid_t id = fork();
if (id == 0) {
	//新进程要执行的逻辑
} else {
   //父进程/原进程要执行的逻辑
}

捕获信号-signal()

原型:

__sighandler_t signal(int signum, sighandler_t handler)

头文件:signal.h

参数:
  signum要捕获的信号,这里要接收的和后面发送的信号相同即可(详见信号
  handler处理器 传入要处理该事件的函数引用

返回值:成功调用会返回处理器的返回值,不成功返回-1

作用:捕获一个信号,并用已定义的处理器进行处理

特性:可以唤醒处于paues挂起的进程

void run() {
	//运行逻辑
}
 
int main(){
	 signal(SIGRTMIN, &run);
}

进程休眠-sleep()

原型:

unsigned int sleep(unsigned int __seconds)
int usleep(__useconds_t __useconds)

头文件:unistd.h

参数:
  __seconds要休眠的秒数
  __useconds要休眠的毫秒数

返回值:剩余秒数

作用:令进程暂停一段时间,直到到达指定时间,或者被中断

usleep(300000);

得到进程id-getpid()

原型:

__pid_t getpid()
__pid_t getppid()

头文件:unistd.h

参数:无

返回值:
  getpid返回当前进程id
  getppid返回父进程id

printf("线程%d正在运行\n", getpid());

进程暂停-pause()

原型:

int pause()

头文件:unistd.h

返回值:只返回-1

作用:令当前进程进入休眠状态,直到被信号唤醒

void toSleep() {
    pause();
}

进程退出-_exit()

原型:

void _exit (int __status)

头文件:unistd.h

参数:__status 状态码,可以设为NULL表示不关心子进程的退出状态

返回值:无

作用:停止进程的运行,并清除其使用的内存空间,以及在内核中的各种数据结构

特性:在进程通过该函数停止后,设置的状态码可以被wait/waitpid获得

void killSelf() {
    _exit(3);
}

发送信号-kill()

原型:

int kill (__pid_t __pid, int __sig)

头文件:signal.h

参数:
  __pid目的进程号
  __sig信号值

返回值:成功返回0,失败返回-1

作用:给一个进程发送信号

特性:该信号可以被signal函数所捕获

void front() {
	//对应前面的signal
	kill(pid, SIGRTMIN);
}

等待进程退出-wait()

原型:

__pid_t wait (int *__stat_loc)
__pid_t waitpid (__pid_t __pid, int *__stat_loc, int __options)

头文件:wait.h

参数:
__pid
   > 0等待指定pid的子进程
   = 0等待进程组码与目前进程相同的任何子进程
   = -1等待任何一个子进程退出
   < -1等待进程组码为指定pid绝对值的任何子进程

__stat_loc:要接收状态码的int的地址,若为NULL则不关心子进程退出状态

__options:对函数进行设置
   WNOHANG若指定进程未结束,该函数则不会阻塞父进程,直接返回0
   WUNTRACED若指定进程已被暂停,且其自暂停以来状态从未返回过,则立即返回其状态
   0:阻塞父进程,等待子进程退出

返回值:
  成功:返回结束的子进程的pid
  失败:返回-1
  若将__options设置为WNOHANG且没有子进程退出则返回0

作用:让父进程等待某一进程(wait)或等待指定进程(waitpid)退出,是否阻塞依照__options参数而定

注意:对于接收状态的__stat_loc参数,如果进程是正常退出,则正常得到状态码。若被信号杀死而退出,则返回的int中,状态码被存在低8位中,需要移位才可得到实际的状态码((t >> 8) & 0x7f)

void kill_() {
    int t;
    kill(pid, SIGTRAP);//搭配kill用
    waitpid(pid, &t, 0);
    printf("线程 %d 已经终结,退出码=>%d\n", pid, (t >> 8) & 0x7f);
}

重置进程-execve()

原型:

int execve (const char *__path, char *const __argv[], char *const __envp[])

头文件:unistd.h

参数:
  __path 命令目录或可执行二进制文件目录
  __argv[] 参数序列
  __envp[] 环境变量

返回值:成功无返回值,失败返回-1

作用:执行一个新的程序或命令

注意:参数序列和环境变量数组需以NULL结尾

int main(){
	pid_t pid = fork();//搭配fork用
	//新进程
	if (pid == 0) {
    	char ch = (char) (i + 48);
    	char *chars = {&ch};
		char *argv[] = {"/tmp/a.out", chars, NULL};
		char *envp[] = {NULL};
		execve("/tmp/a.out", argv, envp);
	} else {
		//父进程/原进程
	}
}


//a.out
int main(int narg, char **args) {
    if (narg == 2) {
    	//如果有参数
        char *mInt = args[1];
        i = mInt[0] - 48;
    } else {
    	//如果无参数
        i = 0;
    }
}

创建信号量-semget()

原型:

int semget (key_t __key, int __nsems, int __semflg)

头文件:sys/sem.h

参数:
  __key 信号量键值,指定为 IPC_PRIVATE 时会创建新的信号量集对象
  __nsems 信号量集中信号量的个数,通常为1
  __semflg 设置为 0 获得信号量集标识符
    设置为 -1 | IPC_CREAT 时创建新信号量集

返回值:成功时返回该信号量集的标识符,失败返回-1

作用:创建信号量集并返回其标识符,或得到一个信号量集标识符

//简单创建一个信号量集
int semid = semget(IPC_PRIVATE, 1, -1 | IPC_CREAT);

操作信号量-semctl()

原型:

int semctl (int __semid, int __semnum, int __cmd, …)

头文件:sys/sem.h

参数:
  __semid 操作的信号量操作符,来自semget函数成功的返回值
  __semnum 操作的信号量级数组的下标,一个信号量为0
  __semnum 对该信号集要进行的操作,以下为部分形参
    IPC_RMID 摧毁该信号量,无需第四个参数
    GETVAL从信号量集中获取指定信号量,返回其值,无需第四个参数
    SETVAL用联合体semun中的val值设置指定信号量的值
  arg 第四个可选参数联合体semun

返回值:
  成功调用返回0
  cmd中的特殊操作返回大于0的特殊值
  失败返回-1

作用:初始化信号量、获得信号量、摧毁信号量

union semun {
    int val;
};

int main(){
	int semidA = semget(IPC_PRIVATE, 1, -1 | IPC_CREAT);
	semctl(semidA, 0, SETVAL, semun);
}

信号量PV操作-semop()

原型:

semop (int __semid, struct sembuf *__sops, size_t __nsops)

头文件:sys/sem.h

参数:
  __semid 操作的信号量操作符,来自semget函数成功的返回值
  __sops 操作控制信号量的结构体数组首地址sembuf
  __nsops 进行操作信号量 的个数,一般为1

返回值:
  成功操作返回信号集标识符
  失败返回-1

作用:完成对信号量的P操作或V操作

int main(){
	//先设置用于操作信号量的结构体
	//P操作
	struct sembuf PD;
    PD.sem_num = 0;
    PD.sem_op = -1;
    PD.sem_flg = SEM_UNDO;

	//V操作
    struct sembuf VU;
    VU.sem_num = 0;
    VU.sem_op = 1;
    VU.sem_flg = SEM_UNDO;
	
	//对信号量集semidA进行操作
	semop(semidA, &PD, 1);
	semop(semidA, &VU, 1);
}

其他

获得真随机数

获得真随机的随机数(其实还是伪随机数)

time_t time (time_t *__timer)

头文件:time.h

参数:__timer 将获得的时间回写到__timer中

返回值:返回从1970-01-01 00:00:00到现在的秒数

注意:当参数为null时,直接返回秒数

void srand (unsigned int __seed)

头文件:stdlib.h

参数:__seed 种子

作用:随机数发生器,重置随机数

注意:参数如未设置,则默认为1

int rand (void)

头文件:stdlib.h

返回值:返回一个0-32767之间的随机数

Q:为什么会出现获得真随机数操作?
A:如果直接使用rand函数产生的数是固定的,一定会以一个固定的顺序出现“随机数”,比如:7,6,2,9,3,1,4,8…。无论启动多少次代码都是这个固定的序列。所以需要使用随机数发生器函数srand来重置随机数。问题又来了,随机数发生器的参数在代码中是人为指定的,所以最终产生的仍然是可预测的“随机数”。最终,时间time是不可预测的,将时间作为种子,这样产生的随机数才是真随机数。

//获得1-10之间的真随机数
int main(){
	srand((unsigned int) time(NULL));
	rand() % 10 + 1;
}

信号signal

64个信号

联合体semun

被定义在linux/sem.h中,示例中自己创建了一个

union semun {
   short val;             /*SETVAL用的值*/
   struct semid_ds* buf;  /*IPC_STAT、IPC_SET用的semid_ds结构*/
   unsigned short* array; /*SETALL、GETALL用的数组值*/
   struct seminfo *buf;   /*为控制IPC_INFO提供的缓存*/
  } arg;

结构体sembuf

被定义在sys/sem.h头文件中,无需自己定义

struct sembuf {
  unsigned short int sem_num;	/* 信号量集中信号量的编号 */
  short int sem_op;				/* 该数值>0 进行V操作信号量值增加,表示进程释放控制的资源。该数值<0 进行P操作信号量值减少 =0 阻塞 */
  short int sem_flg;			/* 0 默认操作 IPC_NOWAIT设置信号量操作不等待 SEM_UNDO 内核记录进程调用操作*/
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值