Skip to content

Instantly share code, notes, and snippets.

@cwshu
Created December 18, 2017 13:47
Show Gist options
  • Save cwshu/c8a74df53cf0a180198dd158c4e47afd to your computer and use it in GitHub Desktop.
Save cwshu/c8a74df53cf0a180198dd158c4e47afd to your computer and use it in GitHub Desktop.
#ifndef _GNU_SOURCE
#define _GNU_SOURCE 1
#endif
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <unistd.h>
#include <spawn.h>
#define FORK_TIME 1024
pid_t fspawn(const char* program){
pid_t child_pid;
child_pid = fork();
if( child_pid == 0 ){
// child
execlp(program, program, NULL);
perror("exec() error");
}
else if( child_pid > 0 ){
// parent
return child_pid;
}
else{
perror("fork() error");
exit(1);
}
}
pid_t pspawn(const char* program, bool is_vfork){
pid_t child_pid = -1;
int ret;
char** argv = NULL;
argv = malloc(sizeof(char*) * 2);
argv[0] = program;
argv[1] = NULL;
posix_spawnattr_t attr;
posix_spawnattr_init(&attr);
int flag = 0;
if( is_vfork ){
flag |= POSIX_SPAWN_USEVFORK;
posix_spawnattr_setflags(&attr, flag);
}
ret = posix_spawnp(&child_pid, program, &attr, NULL, argv, NULL);
if( ret != 0 && child_pid == -1 ){
perror("fork() error");
exit(1);
}
else if( ret != 0 ){
fprintf(stderr, "pre-exec or exec() error");
exit(1);
}
return child_pid;
}
int main(int argc, char *argv[]){
pid_t child_pid;
struct timeval start_time, finish_time, running_time;
// fork-exec
printf("fork-exec\n");
gettimeofday(&start_time, NULL);
for( int i = 0; i < FORK_TIME; i++ ){
child_pid = fspawn("true");
wait(NULL);
}
gettimeofday(&finish_time, NULL);
timersub(&finish_time, &start_time, &running_time);
printf("running time: %ld sec, %ld usec\n", running_time.tv_sec, running_time.tv_usec);
// pspawn
printf("pspawn\n");
gettimeofday(&start_time, NULL);
for( int i = 0; i < FORK_TIME; i++ ){
child_pid = pspawn("true", false);
if( child_pid != -1 ){
wait(NULL);
}
}
gettimeofday(&finish_time, NULL);
timersub(&finish_time, &start_time, &running_time);
printf("running time: %ld sec, %ld usec\n", running_time.tv_sec, running_time.tv_usec);
// pspawn
printf("pspawn vfork\n");
gettimeofday(&start_time, NULL);
for( int i = 0; i < FORK_TIME; i++ ){
child_pid = pspawn("true", true);
if( child_pid != -1 ){
wait(NULL);
}
}
gettimeofday(&finish_time, NULL);
timersub(&finish_time, &start_time, &running_time);
printf("running time: %ld sec, %ld usec\n", running_time.tv_sec, running_time.tv_usec);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment