c语言多进程与多线程函数接口实例源码



c语言多进程与多线程函数实例源码。(1) system函数 → 启动新的进程。

接口:
#include <stdlib.h>
int system(const char *string);
代码:
printf(“begin\n”);
//system(“pa aux”);  //必须等到ps进程结束后才返回。
system(“ps aux &”); // 无须等待,直接返回。
printf(“end\n”);
(2) exec*函数 → 替换旧进程为新进程。
接口:
#include <unistd.h>
int execl(const char *path, const char *arg0, …, (char *)0);
int execlp(const char *file, const char *arg0, …, (char *)0);
int execle(const char *path, const char *arg0, …, (char *)0, char *const envp[ ]);
int execv(const char *path, char *const argv[ ]);
int execvp(const char *file, char *const argv[ ]);
int execve(const char *path, char *const argv[ ], char *const envp[ ]);
代码:
printf(“can print\n”); // 可以打印。
execlp(“ps”, “ps”, “aux”, (char *)0); // 在PATH变量环境中查找”ps”程序。
printf(“can not print\n”); // 不可以打印,因为exec*函数进入新进程就不会返回了,除非出错返回-1。
(3) fork函数 → 复制旧进程给新进程。
接口:
#include <sys/types.h>
#include <unistd.h>
pid_t fork(void);
代码:
pid_t pid = fork(); // 子进程和父进程一样继续执行,不同的是子进程的fork调用返回0,而父进程的fork调用返回子进程的PID。
switch(pid)
{
case -1: // 在父进程中:父进程的fork调用失败,返回-1。
perror(“fork调用失败”);
exit(1);
case 0: // 在子进程中。
printf(“这是子进程\n”);
break;
default: // 在父进程中。
printf(“这是父进程\n”);
break;
}
(4) wait函数 → 父进程挂起,等待子进程结束为止。相当于waitpid(-1, &stat, 0);
接口:
#include <sys/types.h>
#include <sys/wait.h>
pid_t wait(int *status);
代码:
if (pid != 0) // 只有父进程执行。
{
int stat_val;
pid_t child_pid = wait(&stat_val); // 父进程不需要子进程的退出状态,可以用NULL代替&stat_val。
printf(“子进程(pid = %d)已经结束\n”, child_pid);
if (WIFEXITED(stat_val)) // 正常退出返回非0值。
{
printf(“子进程正常结束:退出码为%d\n”, WEXITSTATUS(stat_val)); // 获取子进程的退出码。
}
else
{
printf(“子进程异常终止\n”);
}
}
(5) waitpid函数 → 等待某个指定的子进程结束。
接口:
#include <sys/types.h>
#include <sys/wait.h>
pid_t waitpid(pid_t pid, int *status, int options);
代码:
if (pid != 0)  // 只有父进程执行。
{
pid_t child_pid;
do
{
child_pid = waitpid(pid, NULL, WNOHANG); // WNOHANG表示父进程不挂起。
switch(child_pid)
{
case -1:
perror(“waitpid调用失败”);
return 2;
case 0: // 子进程还在运行返回0。
printf(“子进程还在运行\n”);
sleep(1);
break;
default: // 子进程已经结束返回子进程的PID。
printf(“子进程(pid = %d)已经结束\n”, child_pid);
break;
}
} while (child_pid <= 0);
}
(6) freopen函数 → 重定向。
接口:
#include <stdio.h>
FILE * freopen ( const char * filename, const char * mode, FILE * stream );
代码:
if (!freopen(“file.in”, “r”, stdin)) // 先关闭标准输入流,再将stdin与”file.in”关联起来。
{
fprintf(stderr, “could not redirect stdin from file.in\n”);
exit(1);
}
if (!freopen(“file.out”, “w”, stdout)) // 先关闭标准输出流,再将stdout与”file.out”关联起来。
{
fprintf(stderr, “could not redirect stdout to file.out\n”);
exit(2);
}
(7) signal函数 → 处理信号。更健壮的替代是sigaction函数。
接口:
#include <signal.h>
void (*signal(int sig, void (*func)(int)))(int);
代码:
void ouch(int sig)
{
priintf(“OUCH! 收到中断信号(%d)!\n”, sig);
}
int main()
{
(void)signal(SIGINT, ouch); // 指定SIGINT信号的处理函数为ouch。
}
(8) kill函数 → 发送信号。
接口:
#include <sys/types.h>
#include <signal.h>
int kill(pid_t pid, int sig);
代码:
kill(getppid(), SIGALRM); // 子进程向父进程发送SIGALRM信号。
(9) alarm函数 →  发送SIGALRM信号,超时终止进程。
接口:
#include <unistd.h>
unsigned  int alarm(unsigned int seconds);
代码:
int main()
{
alarm(10);
sleep(5);
int ret = alarm(10); // 返回上次设置的闹钟剩余的秒数。
printf(“剩余时间为%d\n”, ret);
pause(); // 挂起直到遇到一个信号为止。输出”Alarm clock”。
return 0;
}
(10) pause函数 → 挂起直到遇到一个信号为止。更通用的替代是sigsuspend函数。
接口:
#include <unistd.h>
int pause(void);
代码:同(9)。
(11) sigaction函数 → 处理信号。取代signal函数。
接口:
#include <signal.h>
int sigaction(int sig, const struct sigaction *act, struct sigaction *oact);
代码:
void ouch(int sig)
{
priintf(“OUCH! 收到中断信号(%d)!\n”, sig);
}
int main()
{
struct sigaction act;
act.sa_handler = ouch;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
sigaction(SIGINT, &act, 0);
}
(12) 关于信号集的函数:sigaddset()、sigemptyset()、sigfillset()、sigdelset()、sigismember()、sigprocmask()、sigpending()、sigsuspend()八个函数。
接口:
#include <signal.h>
int sigaddset(sigset_t *set, int signo);
int sigemptyset(sigset_t *set);
int sigfillset(sigset_t *set);
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);
int sigpending(sigset_t *set);
int sigsuspend(const sigset_t *sigmask);
代码:(略)