Skip to content

Commit

Permalink
多线程
Browse files Browse the repository at this point in the history
  • Loading branch information
chankeh committed Aug 5, 2017
1 parent 376f9fb commit 1223e78
Show file tree
Hide file tree
Showing 7 changed files with 352 additions and 0 deletions.
32 changes: 32 additions & 0 deletions ch18/Thread1.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#include <stdio.h>
#include <pthread.h>
void * thread_summation(void *arg);

int sum = 0;

int main(int argc, char *argv[]){
pthread_t id_t1,id_t2;
int range1[] = {1,5};
int range2[] = {6,10};

pthread_create(&id_t1,NULL,thread_summation,(void *)range1);
pthread_create(&id_t2,NULL,thread_summation,(void *)range2);

pthread_join(id_t1,NULL);
pthread_join(id_t2,NULL);

printf("sum = %d\n",sum);
return 0;
}

void * thread_summation(void *arg){
int start = ((int *)arg)[0];
int end = ((int *)arg)[1];

while(start <= end){
sum += start;
start++;
}

return NULL;
}
99 changes: 99 additions & 0 deletions ch18/client.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <semaphore.h>
#include <pthread.h>

#define BUF_SIZE 100
#define NAME_SIZE 20

void error_handling(char *message);
void * send_msg(void * arg);
void * recv_msg(void * arg);

char name[NAME_SIZE] = "[DEFAULT]";
char msg[BUF_SIZE];

int main(int argc,char *argv[]){
int sock;
struct sockaddr_in serv_adr;
pthread_t snd_thread,rcv_thread;
void * thread_return;

if(argc != 4){
printf("Usage : %s <IP> <port> <name>\n",argv[0]);
exit(1);
}

sprintf(name,"[%s]",argv[3]);
sock = socket(PF_INET,SOCK_STREAM,0);
if(sock == -1){
error_handling("socket() error");
}

memset(&serv_adr,0,sizeof(serv_adr));
serv_adr.sin_family = AF_INET;
serv_adr.sin_addr.s_addr = inet_addr(argv[1]);
serv_adr.sin_port = htons(atoi(argv[2]));

if(connect(sock,(struct sockaddr *)&serv_adr,sizeof(serv_adr)) == -1){
error_handling("connect() error\r\n");
}else{
printf("Connected....");
}

pthread_create(&snd_thread,NULL,send_msg,(void *)&sock);
pthread_create(&rcv_thread,NULL,recv_msg,(void *)&sock);

pthread_join(snd_thread,&thread_return);
pthread_join(rcv_thread,&thread_return);

close(sock);
return 0;
}

void error_handling(char *message){
fputs(message,stderr);
fputs("\n",stderr);
exit(1);
}

void * send_msg(void *arg){
int sock = *((int *)arg);
char name_msg[NAME_SIZE + BUF_SIZE];

while(1){
fgets(msg,BUF_SIZE,stdin);
if(!strcmp(msg,"q\n") || ! strcmp(msg,"Q\n")){
close(sock);
exit(0);
}

sprintf(name_msg,"%s %s",name,msg);
write(sock,name_msg,strlen(name_msg));
}

return NULL;
}

void * recv_msg(void * arg){
int sock = *((int *)arg);
char name_msg[NAME_SIZE + BUF_SIZE];
int str_len;

while(1){
str_len = read(sock,name_msg,NAME_SIZE+BUF_SIZE-1);

if(str_len == -1){
return (void *) -1;
}

name_msg[str_len] = 0;
fputs(name_msg,stdout);
}

return NULL;
}
49 changes: 49 additions & 0 deletions ch18/critical.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <stdlib.h>

#define NUM_THREAD 100


void * thread_inc(void *arg);
void * thread_des(void *arg);

long long num = 0; //bit64

int main(int argc, char *argv[]){
pthread_t thread_id[NUM_THREAD];
int i;

for(i=0;i<NUM_THREAD;i++){
if(i%2)
pthread_create(&thread_id[i],NULL,thread_inc,NULL);
else
pthread_create(&thread_id[i],NULL,thread_des,NULL);
}
for(i=0;i<NUM_THREAD;i++)
pthread_join(thread_id[i],NULL);

printf("result = %lld\n",num);
return 0;
}

void * thread_inc(void *arg){
int i;

for(i=0;i<50000000;i++){
num += 1;
}

return NULL;
}

void * thread_des(void *arg){
int i;

for(i=0;i<50000000;i++){
num -= 1;
}

return NULL;
}
56 changes: 56 additions & 0 deletions ch18/sem.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>

void * read(void * arg);
void * accu(void * arg);

static sem_t sem_one;
static sem_t sem_two;
static int num;

int main(int argc, char *argv[]){
pthread_t id_t1,id_t2;

sem_init(&sem_one,0,0);
sem_init(&sem_two,0,1);

pthread_create(&id_t1,NULL,read,NULL);
pthread_create(&id_t2,NULL,accu,NULL);

pthread_join(id_t1,NULL);
pthread_join(id_t2,NULL);

sem_destroy(&sem_one);
sem_destroy(&sem_two);

return 0;
}


void * read(void * arg){
int i;

for(i=0;i<5;i++){
printf("Input num %d: \n",i+1);
sem_wait(&sem_two);
scanf("%d",&num);
sem_post(&sem_one);
}

return NULL;
}

void *accu(void *arg){
int sum = 0,i;
for(i=0;i<5;i++){
sem_wait(&sem_one);
sum += num;
printf("sum = %d \n",sum);
sem_post(&sem_two);
}

printf("result : %d \n",sum);

return NULL;
}
116 changes: 116 additions & 0 deletions ch18/server.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <pthread.h>
#include <semaphore.h>

#define BUF_SIZE 100
#define MAX_CLNT 256

void * handle_clnt(void * arg);
void send_msg(char *msg,int len);
void error_handling(char *message);

int clnt_cnt = 0;
int clnt_socks[MAX_CLNT];
pthread_mutex_t mutx;

int main(int argc, char *argv[]){
int serv_sock;
int clnt_sock;
struct sockaddr_in serv_adr;
struct sockaddr_in clnt_adr;
int clnt_adr_sz;
pthread_t t_id;//创建线程id

if(argc != 2){
printf("Usage : %s <port>\n",argv[0]);
exit(1);
}
pthread_mutex_init(&mutx,NULL);//因为是多线程,所以要创建互斥量,以便后期互斥访问临界区

serv_sock = socket(PF_INET,SOCK_STREAM,0);
if(serv_sock == -1){
error_handling("socket() error");
}

memset(&serv_adr,0,sizeof(serv_adr));
serv_adr.sin_family=AF_INET;
serv_adr.sin_addr.s_addr=htonl(INADDR_ANY);
serv_adr.sin_port=htons(atoi(argv[1]));

if(bind(serv_sock,(struct sockaddr*)&serv_adr,sizeof(serv_adr)) == -1){
error_handling("bind() error");
}

if(listen(serv_sock,5) == -1){
error_handling("listen() error");
}

while(1){
clnt_adr_sz = sizeof(clnt_adr);
clnt_sock = accept(serv_sock,(struct sockaddr*)&clnt_adr,&clnt_adr_sz);
pthread_mutex_lock(&mutx);//通过加锁机制,保护临界区
clnt_socks[clnt_cnt++] = clnt_sock;//临界区代码
pthread_mutex_unlock(&mutx);//释放临界区

pthread_create(&t_id,NULL,handle_clnt,(void *)&clnt_sock);
pthread_detach(t_id);//销毁线程
printf("Connetcted client IP :%s \n",inet_ntoa(clnt_adr.sin_addr));
}

close(serv_sock);

return 0;
}

void error_handling(char *message){

fputs(message,stderr);
fputs("\n",stderr);
exit(1);
}

void * handle_clnt(void * arg){
int clnt_sock = *((int *)arg);
int str_len =0;
int i;
char msg[BUF_SIZE];

while((str_len = read(clnt_sock,msg,sizeof(msg))) != 0)
send_msg(msg,str_len);

pthread_mutex_lock(&mutx);//临界区代码加锁
for(i=0;i<clnt_cnt;i++){
if(clnt_sock == clnt_socks[i]){
while(i++ < clnt_cnt - 1)
clnt_socks[i] = clnt_socks[i+1];
break;
}
}

clnt_cnt--;
pthread_mutex_unlock(&mutx);
close(clnt_sock);

return NULL;
}

//send to all
void send_msg(char *msg,int len)
{
int i;

pthread_mutex_lock(&mutx);
for(i=0;i<clnt_cnt;i++){
write(clnt_socks[i],msg,len);
}

pthread_mutex_unlock(&mutx);
}
Binary file not shown.
Binary file added ch18/多线程服务器端的实现2.docx
Binary file not shown.

0 comments on commit 1223e78

Please sign in to comment.