使用线程缘由
1)fork 代价昂贵
2)fork 返回之后父子进程信息传递需要通过IPC机制
同一进程内的线程除共享全局变量外还共享:
a)进程指令
b)大多数数据
c)打开的文件描述符
d)信号处理函数和处理
e)当前工作目录
f)用户ID和组ID
不过每个线程有各自的
a)线程ID
b)寄存器集合
c)栈
d)errno
e)信号掩码
f)优先级
使用线程的tcp回射服务程序
#include <time.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <stdlib.h>
void
str_echo(int sockfd)
{
ssize_t n;
char buf[1024];
while ( (n = read(sockfd, buf, 1024)) > 0)
write(sockfd, buf, n);
if (n < 0)
printf("str_echo: read error");
}
static void *
doit(void *arg)
{
int connfd;
connfd = *((int*)arg);
free(arg);
pthread_detach(pthread_self());
str_echo(connfd);
close(connfd);
return NULL;
}
int main(int argc, char** argv)
{
struct sockaddr_in servaddr;
int sockfd, *iptr;
pthread_t tid;
socklen_t addrlen,len;
struct sockaddr *cliaddr;
if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
{
printf("sock error\r\n");
return 0;
}
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(13000);
servaddr.sin_addr.s_addr = inet_addr("0.0.0.0");
if( bind(sockfd, (struct sockaddr* )&servaddr, sizeof(servaddr)) < 0)
{
printf("bind error\r\n");
return 0;
}
if(listen(sockfd, 10) < 0)
{
printf("listen error\r\n");
return 0;
}
cliaddr = malloc(addrlen);
for( ; ;)
{
len = addrlen;
iptr = malloc(sizeof(int));
*iptr = accept(sockfd, cliaddr, &len);
pthread_create(&tid,NULL, &doit, iptr);
}
}
注意的地方
编译
gcc tcp_sever_thread.c -o sever -pthread