多进程服务端代码:
#include <serversocket.h>
#include <clientsocket.h>
#include <iostream>
#include <signal.h>
#include <sys/wait.h>
using namespace std;
ServerSocket ssocket;
ClientSocket clientSocket;
//父进程退出时的信号处理函数
void sighandle_term(int sig)
{
//防止信号处理函数被新的信号中断
signal(SIGINT, SIG_IGN);
signal(SIGTERM, SIG_IGN);
//通知进程组内所有子进程退出
kill(0, SIGTERM);
ssocket.close();
exit(0);
}
//子进程退出时父进程的信号处理函数
void sighandle_chld(int sig)
{
//防止信号处理函数被新的信号中断
signal(SIGINT, SIG_IGN);
signal(SIGTERM, SIG_IGN);
int pid;
while(pid = waitpid(-1, NULL, WNOHANG) > 0)
{
cout << "child process exited, pid = " << pid << endl;
}
signal(SIGINT, sighandle_term);
signal(SIGTERM, sighandle_term);
}
//子进程退出时子进程的信号处理函数
void sighandle_childExit(int sig)
{
//防止信号处理函数被新的信号中断
signal(SIGINT, SIG_IGN);
signal(SIGTERM, SIG_IGN);
clientSocket.close();
exit(0);
}
int main()
{
signal(SIGCHLD, sighandle_chld);
signal(SIGINT, sighandle_term);
signal(SIGTERM, sighandle_term);
clientSocket.close();
if (ssocket.fd() < 0)
{
exit(1);
}
char host[] = "127.0.0.1";
int port = 9998;
if (!ssocket.bind(host, port))
{
ssocket.close();
exit(1);
}
if (!ssocket.listen(128))
{
ssocket.close();
exit(1);
}
while (true)
{
int cfd = ssocket.accept();
if (cfd < 0)
{
ssocket.close();
exit(1);
}
ClientSocket csocket(cfd);
int pid = fork();
if (pid > 0)
{
csocket.close();
continue;
}
else if(pid < 0) //系统资源不足
{
perror("fork error:");
ssocket.close();
csocket.close();
exit(1);
}
signal(SIGINT, sighandle_childExit);
signal(SIGTERM, sighandle_childExit);
clientSocket.setFd(cfd);
ssocket.close();
char recvbuf[1024];
if (csocket.recv(recvbuf, sizeof(recvbuf)) < 0)
{
csocket.close();
exit(1);
}
cout << "Recieve: clientfd = " << cfd << ", message = " << recvbuf << endl;
char sendbuf[] = "Server recieved your message";
if (csocket.send(sendbuf, sizeof(sendbuf)) < 0)
{
csocket.close();
exit(1);
}
csocket.close();
exit(0);
}
ssocket.close();
return 0;
}
多线程服务端代码:
#include <iostream>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>
#include <pthread.h>
#include <serversocket.h>
#include <clientsocket.h>
using namespace std;
void *task_thread(void *arg)
{
ClientSocket client = *(ClientSocket *)arg;
char recvbuf[1024] = {0};
size_t len = client.recv(recvbuf, sizeof(recvbuf));
if (len > 0)
{
cout << "recieved from client: " << recvbuf << endl;
char sendbuf[1024] = "recieved your message";
client.send(sendbuf, sizeof(sendbuf));
}
client.close();
}
int main()
{
char host[] = "127.0.0.1";
int port = 9999;
ServerSocket ssocket;
if (ssocket.fd() < 0)
{
exit(1);
}
if (!ssocket.bind(host, port))
{
ssocket.close();
exit(1);
}
if (!ssocket.listen(128))
{
ssocket.close();
exit(1);
}
while (true)
{
int connfd = ssocket.accept();
if (connfd < 0)
{
continue;
}
ClientSocket csocket(connfd);
pthread_t tid = -1;
//设置线程分离属性
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
int ret = pthread_create(&tid, &attr, task_thread, &csocket);
if (ret != 0)
{
perror("create thread failed:");
exit(1);
}
}
ssocket.close();
return 0;
}
线程独立资源包括:栈空间、线程id、errno变量、信号屏蔽字、调度优先级,共享的资源有:堆空间、文件描述符表、信号处理方法、当前工作目录、用户id和组id
pthread_t pthread_self(); 该函数总是成功
int pthread_equal(pthread_t t1, pthread_t t2); 相同返回非0
int pthread_create(pthread_t *tid, const pthread_attr_t *attr, void *(*start_routine)(void ),void arg);
attr参数一般为NULL
#include<pthread.h>
CmakeLists: link_libraries(pthread)
pthread有两种状态:joinable非分离和unjoinable分离
joinable状态,当线程函数自己返回退出时或pthread_exit()时都不会释放线程占用的堆栈和线程描述符(总计8k多),只有调用了pthread_join之后资源才会被释放。
unjoinable状态,资源在线程函数退出或pthread_exit时自动释放。该状态可以在创建线程时指定,或在线程创建之后在线程函数开头detach自己:pthread_detach(pthread_self()),在线程函数中就可以直接调用pthread_exit(NULL)退出。
int pthread_join(pthread_t thread, void retval):**子线程合入主线程,主线程阻塞并等待子线程结束。
retval是用户定义的指针,用来存储被等待线程的返回值。
返回0代表成功,失败返回的是错误号。
int pthread_detach(pthread_t tid),成功后返回0,如果tid是分离线程或者不是当前进程中的有效线程则返回错误。
分离状态的线程不可以被join
void pthread_exit(void retval)* 内部结束,线程终止,返回数据
int pthread_cancel(pthread_t thread) 线程函数外部取消线程
线程清理:
void pthread_cleanup_push(void (routine)(void), void* arg);
void pthread_cleanup_pop(int execute);
线程属性:
pthread_attr_t