#include <cstdlib>
#include <iostream>
#include <memory>
#include <thread>
#include <mutex>
#include <future>
#include <atomic>
#include <queue>
#include <vector>
#include <utility>
#include <functional>
template <typename T, typename...Args>
class thread_safe_queue
{
private:
using fun_type = std::function<T(Args...)>;
std::mutex mut;
std::queue<fun_type> data_queue;
std::condition_variable data_cond;
public:
thread_safe_queue() {}
template<typename C>
void push(C&& new_value)
{
std::lock_guard<std::mutex> lk(mut);
data_queue.push(std::move(new_value));
data_cond.notify_one();
}
template<typename C>
void wait_and_pop(C&& value)
{
std::unique_lock<std::mutex> lk(mut);
data_cond.wait(lk, [this] {return !data_queue.empty(); });
value = std::move(data_queue.front());
data_queue.pop();
}
template<typename C>
std::shared_ptr<C> wait_and_pop()
{
std::unique_lock<std::mutex> lk(mut);
data_cond.wait(lk, [this] {return !data_queue.empty(); });
std::shared_ptr<C> res(std::make_shared<T>(std::move(data_queue.front())));
data_queue.pop();
return res;
}
bool try_pop(fun_type& value)
{
std::lock_guard<std::mutex> lk(mut);
if (data_queue.empty())
return false;
value = std::move(data_queue.front());
data_queue.pop();
return true;
}
template<typename C>
std::shared_ptr<C> try_pop()
{
std::lock_guard<std::mutex> lk(mut);
if (data_queue.empty())
return std::shared_ptr<C>();
std::shared_ptr<C> res(std::make_shared<C>(std::move(data_queue.front())));
data_queue.pop();
return res;
}
bool empty()
{
std::lock_guard<std::mutex> lk(mut);
return data_queue.empty();
}
};
class join_threads
{
std::vector<std::thread>& threads;
public:
explicit join_threads(std::vector<std::thread>& threads_) :
threads(threads_)
{ }
~join_threads()
{
for (unsigned long i = 0; i < threads.size(); i++)
{
if (threads[i].joinable())
threads[i].join();
}
}
};
template<typename R, typename ...Args>
class thread_pool
{
private:
std::atomic_bool done;
thread_safe_queue<R, Args... > work_queue;
std::vector <std::shared_ptr<std::thread>> threads;
//join_threads join
public:
void worker_thread(Args&&...args)
{
while (!done)
{
std::function<R(Args...)>task;
if (work_queue.try_pop(task))
{
task(std::move(args)...);
}
else
{
std::this_thread::yield();
}
}
}
public:
thread_pool() { done = false; }
void start(Args...args)
{
unsigned const thread_count = std::thread::hardware_concurrency();
try
{
for (unsigned i = 0; i < thread_count; ++i)
{
threads.emplace_back(std::make_shared<std::thread>(&thread_pool<R, Args...>::worker_thread, this, args...));
}
}
catch (...)
{
done = true;
throw;
}
}
~thread_pool()
{
done = true;
for (unsigned long i = 0; i < threads.size(); i++)
{
if (threads[i]->joinable())
threads[i]->join();
}
}
void sumit(std::function<R(Args...)>(f))
{
work_queue.push(std::function<R(Args...)>(f));
}
//rest as before
};
//int fun(int i)
//{
// std::cout << "good,works!" << "1" << std::endl;
// return 6;
//}
//void fun2(int i, char c, double d)
//{
// std::cout << i << " " << c << " " << d << std::endl;
//}
//int main()
//{
// thread_pool<void, int, char, double > p ;
// p.sumit(fun2);
// p.start(1,'2',3.999);
// return 0;
//}
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/epoll.h>
#include <errno.h>
#include <ctype.h>
#include <iostream>
#include "thread_pool_args.h"
#define MAXLINE 8192
#define OPEN_MAX 5000
#define SERV_PORT 8000
thread_pool<void,int,char*,int> pool;
void handle_function(int sockfd,char* buffer, int n)
{
for(int i = 0; i < n; i++)
buffer[i] = toupper(buffer[i]);
write(STDOUT_FILENO, buffer,n);
write(sockfd, buffer,n);
}
void perr_exit(const char *s)
{
perror(s);
exit(-1);
}
int main(int argc, char *argv[])
{
int listenfd, connfd,sockfd;
int i, n, num = 0;
ssize_t nready, efd, res;
char str[INET_ADDRSTRLEN],buffer[MAXLINE];
socklen_t clilen;
struct sockaddr_in cliaddr, servaddr;
struct epoll_event tep, ep[OPEN_MAX]; //tep: epoll_ctl参数 ep[] : epoll_wait参数
listenfd = socket(AF_INET, SOCK_STREAM, 0);
int opt = 1;
setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); //端口复用
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(SERV_PORT);
bind(listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr));
listen(listenfd, 20);
efd = epoll_create(OPEN_MAX); //创建epoll模型, efd指向红黑树根节点
if (efd == -1)
perr_exit("epoll_create error");
tep.events = EPOLLIN; tep.data.fd = listenfd; //指定lfd的监听时间为"读"
res = epoll_ctl(efd, EPOLL_CTL_ADD, listenfd, &tep); //将lfd及对应的结构体设置到树上,efd可找到该树
if (res == -1)
perr_exit("epoll_ctl error");
for ( ; ; ) {
/*epoll为server阻塞监听事件, ep为struct epoll_event类型数组, OPEN_MAX为数组容量, -1表永久阻塞*/
nready = epoll_wait(efd, ep, OPEN_MAX, -1);
if (nready == -1)
perr_exit("epoll_wait error");
for (i = 0; i < nready; i++) {
if (!(ep[i].events & EPOLLIN)) //如果不是"读"事件, 继续循环
continue;
if (ep[i].data.fd == listenfd) { //判断满足事件的fd是不是lfd
clilen = sizeof(cliaddr);
connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &clilen); //接受链接
printf("received from %s at PORT %d\n",
inet_ntop(AF_INET, &cliaddr.sin_addr, str, sizeof(str)),
ntohs(cliaddr.sin_port));
printf("cfd %d---client %d\n", connfd, ++num);
tep.events = EPOLLIN; tep.data.fd = connfd;
res = epoll_ctl(efd, EPOLL_CTL_ADD, connfd, &tep);
if (res == -1)
perr_exit("epoll_ctl error");
} else { //不是lfd,
sockfd = ep[i].data.fd;
n = read(sockfd, buffer, MAXLINE);
if (n == 0) { //读到0,说明客户端关闭链接
res = epoll_ctl(efd, EPOLL_CTL_DEL, sockfd, NULL); //将该文件描述符从红黑树摘除
if (res == -1)
perr_exit("epoll_ctl error");
close(sockfd); //关闭与该客户端的链接
printf("client[%d] closed connection\n", sockfd);
} else if (n < 0) { //出错
perror("read n < 0 error: ");
res = epoll_ctl(efd, EPOLL_CTL_DEL, sockfd, NULL);
close(sockfd);
} else {
pool.sumit(handle_function);
pool.start(sockfd,buffer,n) ; //实际读到了字节数
}
}
}
}
close(listenfd);
close(efd);
return 0;
}
#include <iostream>
#include <string>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define REQUEST 400
#define REPLY 400
#define UDP_SERV_PORT 7777
#define TCP_SERV_PORT 8000
using namespace std;
int main(int argc, char *argv[])
{
struct sockaddr_in serv;
char request[REQUEST] = {'\0'}, reply[REPLY]={'\0'};
int sockfd;
int nleft, nread;
strcpy(request,"test\n");
strcpy(reply,"good,well,better,best\n");
// if(argc != 2)
// cerr<<"usage: tcpcli <IP address of server>"<<endl;
if((sockfd = socket(PF_INET,SOCK_STREAM,0)) < 0)
cerr<<"socket error"<<endl;
memset(&serv,0,sizeof (serv));
serv.sin_family = AF_INET;
serv.sin_addr.s_addr = inet_addr("127.0.0.1");
serv.sin_port = htons(TCP_SERV_PORT);
if((connect(sockfd,(struct sockaddr*)&serv,sizeof(serv)) )< 0)
cerr<<"connect error"<<endl;
if( write(sockfd,request,REQUEST) != REQUEST)
cerr<<"write error"<<endl;
nleft = REPLY;
const char* ptr = reply;
while (nleft > 0) {
if((nread = write(sockfd,(char*)ptr,REPLY) ) < 0)
return nread;
else if (nread == 0)
break;
nleft -= nread;
ptr += nread;
}
close(sockfd);
return 0;
}
while true ;do "hello"; sleep 2; done;
while true; do command; sleep 2; done;