<二>、进程-(eixt)(_exit)(atexit)(exec)

本文深入探讨了程序开发中的核心流程及关键函数,包括`exit`、`_exit`、`atexit`、`exec`等,详细解释了它们的功能、用法和应用场景。通过实际代码示例,展示了这些函数如何在程序中执行流程控制和资源清理,对于理解程序生命周期和错误处理至关重要。

《exit函数实现》

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int main (void )
{
 pid_t ret;

 printf("hello!\n");
 
   printf("In parent process, pid =%d", getpid());
 exit(0); 
 return 0;
}

结果:

hello!
In parent process, pid =3342
********************************************************

《_exit函数实现》

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>

int main (void )
{
 pid_t ret;

 printf("hello!\n");
 printf("22hello!\n");
 printf("two hello!");
   printf("In parent process, pid =%d", getpid());
 _exit(0); 
 printf(" e next hello!\n");
 printf(" e frok hello!");
 return 0;
}

结果:
hello!
22hello!

********************************************************

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
void exit_func1(void)
{
 printf("exit_func1\n");
}

void exit_func2(void)
{
        printf("exit_func2\n");
}

int main (void )
{
// pid_t ret;

 printf("hello!\n");

 atexit(exit_func1);
 atexit(exit_func2);

   printf("In parent process, pid =%d", getpid());
 exit(0); 
 printf("newver be dispalyed\n");
 return 0;
}

结果:

hello!
In parent process, pid =3554exit_func2
exit_func1

-----------

main主函数执行完毕后,是否可能会再执行一段代码?
如果需的话,可以用ateixt()函数注册一个函数:
 1 #include<stdio.h>
  2 #include<stdlib.h>
  3
  4 void fumc1()
  5 {printf("next\n");}
  6
  7 void fumc2()
  8 {printf("executed");}
  9 void fumc3()
 10 {printf("is");}
 11 void fumc4()
 12 {printf("this");}
 13
 14 void main()
 15 {
 16     char str[]="0123456789";
 17 atexit(fumc1);
 18 atexit(fumc2);
 19 atexit(fumc3);
 20 atexit(fumc4);
 21 printf("This is execued frist. \n");
 22 printf("%d\n",sizeof(str));
 23}
结果:
This is execued frist.
11
thisisexecutednext
本来到该结束程序printf("%d\n",sizeof(str));,
但是还打印thisisexecutednext
说明:该程序结束后,还运行atexit函数
而且到过来运行
****************************************************

《exec函数实现》

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main (void )
{ pid_t ret;
 printf("hello!\n");
 ret = fork();
 printf("Have forked!\n");
 if (ret < 0 ) {
  perror("fork");
  exit(1); }
 if (ret == 0 ) {  //子进程  
//printf("In child process, pid=%d, ppid=%d\n", getpid(), getppid());
  if (execl("/bin/ls", "ls", "-al", NULL) <0 ) {
   perror("execl error!");
   exit(1); 
  }
  printf("Can't run to here in normal!\n");
//     execlp("ls", "ls", "-al", NULL);
   exit(0); }
 sleep(5);
   printf("In parent process, pid =%d, child pid=%d\n", getpid(), ret);
 return 0;
}

结果:


hello!
Have forked!
Have forked!
total 108
drwxrwxrwx 2 nobody nogroup  4096 2011-12-07 18:06 .
drwxrwxrwx 9 lsb    lsb      4096 2011-12-07 18:00 ..
-rwxr--r-- 1 nobody nogroup   380 2011-07-20 23:58 atexit.c
-rwxr-xr-x 1 lsb    lsb      7861 2011-12-07 02:33 c
-rwxr--r-- 1 nobody nogroup  3527 2011-12-07 02:33 c.c
-rwxr-xr-x 1 lsb    lsb      7350 2011-12-07 18:06 exec
-rwxr--r-- 1 nobody nogroup   601 2011-07-20 23:47 exec.c
-rwxr-xr-x 1 lsb    lsb      7202 2011-12-07 18:04 exit
-rwxr--r-- 1 nobody nogroup   193 2011-07-20 23:51 _exit.c
-rwxr--r-- 1 lsb    lsb       194 2011-12-07 18:04 exit.c
-rwxrwxrwx 1 root   root     7350 2011-12-07 02:20 fork
-rwxrwxrwx 1 nobody nogroup   502 2011-07-20 23:40 fork.c
prw-r--r-- 1 lsb    lsb         0 2011-12-07 02:30 in1
prw-r--r-- 1 lsb    lsb         0 2011-12-07 02:30 in2
-rwxr-xr-x 1 lsb    lsb      7508 2011-12-07 02:26 pipe
-rwxrwxrwx 1 nobody nogroup  1378 2008-12-19 03:17 pipe.c
-rwxr-xr-x 1 lsb    lsb      7528 2011-12-07 02:30 pipe_select
-rwxr--r-- 1 nobody nogroup  3029 2008-12-19 03:17 pipe_select.c
-rwxr-xr-x 1 lsb    lsb     12180 2011-12-07 02:35 s
-rwxr--r-- 1 nobody nogroup  4865 2011-12-07 02:32 s.c
In parent process, pid =3157, child pid=3158
************************************************************************

 

 

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <pthread.h> #include <sys/stat.h> #include <fcntl.h> #include <dirent.h> #include <sys/sendfile.h> #include <sys/wait.h> #include <sys/epoll.h> #define PORT 8080 #define MAX_PATH 1024 #define BUFFER_SIZE 4096 #define MAX_EVENTS 64 /* 基础目录定义*/ const char *BASE_DIR = "./web"; /* URL路径映射函数*/ void map_url_to_path(char *url_path, char *file_path) { /* 默认路由处理*/ if (strcmp(url_path, "/") == 0) { snprintf(file_path, MAX_PATH, "%s/Index.html", BASE_DIR); return; } /* 特殊目录映射*/ if (strncmp(url_path, "/images/", 8) == 0) { snprintf(file_path, MAX_PATH, "%s/images%s", BASE_DIR, url_path + 7); return; } /* 通用文件映射*/ snprintf(file_path, MAX_PATH, "%s%s", BASE_DIR, url_path); } /* 获取MIME类型*/ const char *get_mime_type(const char *path) { const char *ext = strrchr(path, '.'); if (!ext) return "text/plain"; if (strcmp(ext, ".html") == 0) return "text/html"; if (strcmp(ext, ".css") == 0) return "text/css"; if (strcmp(ext, ".js") == 0) return "application/javascript"; if (strcmp(ext, ".jpg") == 0) return "image/jpeg"; if (strcmp(ext, ".png") == 0) return "image/png"; if (strcmp(ext, ".json") == 0) return "application/json"; return "text/plain"; } /* 处理HTTP请求*/ void *handle_request(int client_socket) { char buffer[BUFFER_SIZE]; read(client_socket, buffer, BUFFER_SIZE - 1); /* 解析请求行*/ char *method = strtok(buffer, " "); char *url_path = strtok(NULL, " "); if (!url_path) return NULL; /* 映射到本地文件路径*/ char file_path[MAX_PATH]; map_url_to_path(url_path, file_path); /* 检查文件是否存在*/ struct stat file_stat; if (stat(file_path, &file_stat) < 0) { const char *not_found = "HTTP/1.1 404 Not Found\r\nContent-Length: 0\r\n\r\n"; write(client_socket, not_found, strlen(not_found)); close(client_socket); return NULL; } /* 处理目录请求(列出目录内容)*/ if (S_ISDIR(file_stat.st_mode)) { DIR *dir = opendir(file_path); if (!dir) { perror("opendir"); close(client_socket); return NULL; } char dir_list[4096] = "<html><body><ul>"; struct dirent *entry; while ((entry = readdir(dir)) != NULL) { if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) continue; snprintf(dir_list + strlen(dir_list), sizeof(dir_list) - strlen(dir_list), "<li><a href=\"%s\">%s</a></li>", entry->d_name, entry->d_name); } strcat(dir_list, "</ul></body></html>"); closedir(dir); char header[512]; snprintf(header, sizeof(header), "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\nContent-Length: %ld\r\n\r\n", strlen(dir_list)); write(client_socket, header, strlen(header)); write(client_socket, dir_list, strlen(dir_list)); close(client_socket); return NULL; } /* 打开文件*/ int fd = open(file_path, O_RDONLY); if (fd < 0) { perror("open"); close(client_socket); return NULL; } /* 构建响应头*/ char header[512]; snprintf(header, sizeof(header), "HTTP/1.1 200 OK\r\n" "Content-Type: %s\r\n" "Content-Length: %ld\r\n\r\n", get_mime_type(file_path), file_stat.st_size); /* 发送响应*/ write(client_socket, header, strlen(header)); off_t offset = 0; sendfile(client_socket, fd, &offset, file_stat.st_size); close(fd); close(client_socket); return NULL; } /* 主函数(多线程)*/ int main() { int server_fd; struct sockaddr_in address; int addrlen = sizeof(address); server_fd = socket(AF_INET, SOCK_STREAM, 0); /*设置套接字选项*/ int opt = 1; setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); /* 创建套接字*/ if (server_fd == 0) { perror("socket failed"); exit(EXIT_FAILURE); } /* 配置服务器地址*/ address.sin_family = AF_INET; address.sin_addr.s_addr = INADDR_ANY; address.sin_port = htons(PORT); /* 绑定端口*/ if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) { perror("bind failed"); exit(EXIT_FAILURE); } /* 开始监听*/ if (listen(server_fd, 10) < 0) { perror("listen failed"); exit(EXIT_FAILURE); } printf("Web server running at http://localhost:%d\n", PORT); /*创建epoll实例*/ int epoll_fd = epoll_create1(0); if (epoll_fd < 0) { perror("epoll_createl failed"); close(server_fd); eixt(EXIT_FAILURE); } /*添加服务器套接字到epoll*/ struct epoll_event ev; ev.events = EPOLLIN; ev.data.fd = server_fd; if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, server_fd, &ev) < 0) { perror("epoll_ctl: server_fd"); close(server_fd); close(epoll_fd); eixt(EXIT_FAILURE); } struct epoll_event events[MAX_EVENTS]; while (1) { int nfds = epoll_wait(epoll_fd, events, MAX_EVENTS, -1); if (nfds < 0) { perror("epoll_wait"); continue; } for (int i = 0; i < nfds; i++) { if (events[i].data.fd == server_fd) { /* 处理新连接*/ struct sockaddr_in client_addr; socklen_t addr_len = sizeof(client_addr); int client_fd = accept4(server_fd, (struct sockaddr *)&client_addr, &addr_len, SOCK_NONBLOCK); if (client_fd < 0) { perror("accept4 failure"); continue; } printf("New connection from %s:%d\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port)); /*添加新客户端到epoll*/ ev.events = EPOLLIN | EPOLLET; ev.data.fd = client_fd; if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, client_fd, &ev) < 0) { perror("epoll_ctl: client_fd failed"); close(client_fd); } } else { /*处理客户端需求*/ handle_request(events[i].data.fd); } } } close(server_fd); close(epoll_fd); return 0; } 多路复用代码,还需要修改你帮我改一下主函数里面的使他能运行起来
08-15
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值