在主線程的末尾,我有一段打印的代碼:
我執(zhí)行了代碼之后,有時(shí)候可以打印出結(jié)果,有時(shí)候卻不可以打印結(jié)果:
那么是否和我想的那樣,子線程退出會(huì)導(dǎo)致主線程退出?
(這個(gè)程序是一個(gè)壓力測(cè)試程序,bug有點(diǎn)多)
詳細(xì)代碼如下:
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
#include <sys/param.h>
#include <rpc/types.h>
#include <getopt.h>
#include <strings.h>
#include <time.h>
#include <signal.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <errno.h>
#include <fcntl.h>
#include <pthread.h>
int request_nums = 1;
int already_request_nums = 0;
int clients_num = 1;
int thread_nums = 1;
int failed = 0;
int success = 0;
int benchtime = 1; // 默認(rèn)持續(xù)發(fā)起請(qǐng)求的時(shí)間
int timerexpired = 0; // 是否請(qǐng)求到指定的時(shí)間(1表示時(shí)間到,0表示沒(méi)到時(shí)間)
int start = 0; //開(kāi)始/關(guān)閉標(biāo)志
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
const int MAX_LINE = 2048;
const int port = 80;
// 請(qǐng)求行的最大長(zhǎng)度
const int request_size = 2048;
char request[request_size];
const int url_max_size = 100;
char url[url_max_size];
// 發(fā)起請(qǐng)求
void *bench(void *arg);
// 構(gòu)造請(qǐng)求行
void build_request(const char *url);
ssize_t readline(int fd, char *vptr, size_t maxlen);
// 返回已經(jīng)建立連接的套接字
int create_socket (const char *host);
// 設(shè)置非阻塞
void setnonblocking(int sock);
void timeover(int sig) {
timerexpired = 1;
}
// 顯示錯(cuò)誤,并且結(jié)束進(jìn)程
void error_die( const char *sc ) {
perror(sc);
exit(1);
}
/*
作用:設(shè)置文件描述符的狀態(tài)為非阻塞的
參數(shù)1:需要修改狀態(tài)的文件描述符
*/
void setnonblocking(int sock) {
int opts;
opts=fcntl(sock, F_GETFL);
if(opts<0) {
error_die("fcntl(sock,GETFL)");
}
opts = opts | O_NONBLOCK;
if(fcntl(sock, F_SETFL, opts)<0) {
error_die("fcntl(sock,SETFL,opts)");
}
}
void *bench(void *arg) {
int req_len;
int sockfd[clients_num];
char buf[1024];
req_len = strlen(request); // 請(qǐng)求行的長(zhǎng)度
// 創(chuàng)建套接字
for (int i = 0; i < clients_num; ++i) {
sockfd[i] = create_socket(url);
if(sockfd[i] < 0) { // 連接服務(wù)器失敗,所以算一次請(qǐng)求失敗
pthread_mutex_lock(&lock);
failed++;
pthread_mutex_unlock(&lock);
continue;
}
}
while(!start) {};
while(1) {
if (timerexpired) { // 時(shí)間到了,說(shuō)明上一次線程在請(qǐng)求連接的過(guò)程中可能被打斷了,所以不算失敗
if (failed > 0) {
pthread_mutex_lock(&lock);
--failed;
pthread_mutex_unlock(&lock);
}
// pthread_exit((void*)0);
}
for (int i = 0; i < clients_num; ++i) {
int n = write(sockfd[i], request, req_len);
if(n < 0) { // 沒(méi)有一次發(fā)送完,也算做一次請(qǐng)求失敗
pthread_mutex_lock(&lock);
failed++;
pthread_mutex_unlock(&lock);
continue;
}
int m = read(sockfd[i], buf, 1024);
// printf("%s\n", buf);
memset(buf, '\0', 1024);
if (m > 0) {
pthread_mutex_lock(&lock);
++success;
pthread_mutex_unlock(&lock);
}
}
}
for (int i = 0; i < clients_num; ++i) {
close(sockfd[i]);
}
// pthread_exit((void*)0);
}
// 構(gòu)造請(qǐng)求頭
void build_request(const char *url) {
bzero(request, request_size);
strcpy(request, "GET");
strcat(request, " ");
strcat(request, "/");
strcat(request, " ");
strcat(request, "HTTP/1.1");
strcat(request, "\n");
strcat(request, "host: localhost");
strcat(request, "\n\n");
}
/*readline函數(shù)實(shí)現(xiàn)*/
ssize_t readline(int fd, char *vptr, size_t maxlen) {
ssize_t n, rc;
char c, *ptr;
ptr = vptr;
for (n = 1; n < maxlen; n++) {
if ( (rc = read(fd, &c,1)) == 1) {
*ptr++ = c;
if (c == '\n')
break; /* newline is stored, like fgets() */
} else if (rc == 0) {
*ptr = 0;
return(n - 1); /* EOF, n - 1 bytes were read */
} else
return(-1); /* error, errno set by read() */
}
*ptr = 0; /* null terminate like fgets() */
return(n);
}
int create_socket (const char *host) {
/*聲明套接字和鏈接服務(wù)器地址*/
int sockfd;
struct sockaddr_in servaddr;
/*(1) 創(chuàng)建套接字*/
if((sockfd = socket(AF_INET , SOCK_STREAM , 0)) == -1) {
error_die("socket error");
}
/*(2) 設(shè)置鏈接服務(wù)器地址結(jié)構(gòu)*/
bzero(&servaddr , sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(port); // 默認(rèn)為8080端口
if(inet_pton(AF_INET , host , &servaddr.sin_addr) < 0) {
printf("inet_pton error for %s\n", host);
exit(1);
}
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) {
return sockfd;
}
if (connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) {
perror("連接服務(wù)器失敗");
return -1;
}
return sockfd;
}
int main(int argc, char **argv) {
int ch;
pthread_attr_t attr;
struct sigaction action;
// 解析命令行
while((ch = getopt(argc, argv, "n:c:p:u:")) != -1) {
switch(ch) {
case 'n': // 總的請(qǐng)求數(shù)
request_nums = atoi(optarg);
break;
case 'c': // 模擬出的客戶端數(shù)目
clients_num = atoi(optarg);
break;
case 'p': // 總的線程個(gè)數(shù)
thread_nums = atoi(optarg);
break;
case 'u': // 目標(biāo)url
strcpy(url, optarg);
break;
}
}
build_request(url); // 構(gòu)造請(qǐng)求行
pthread_attr_init(&attr);
//注冊(cè)信號(hào)處理函數(shù)
action.sa_handler = timeover;
sigemptyset(&action.sa_mask);
action.sa_flags = 0;
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
pthread_t tid[thread_nums];
for (int i = 0; i < thread_nums; ++i) {
/*創(chuàng)建子線程來(lái)對(duì)服務(wù)器進(jìn)行連接*/
if(pthread_create(&tid[i] , NULL , bench, NULL) == -1) {
perror("pthread create error.\n");
exit(1);
}
}
if(sigaction(SIGALRM, &action, NULL) < 0 ) {
error_die("sigaction:");
}
alarm(benchtime);
start = 1; // 開(kāi)始
printf("總的請(qǐng)求數(shù)%d\n", request_nums);
printf("連接數(shù)%d\n", clients_num);
printf("線程數(shù)目%d\n", thread_nums);
while(!timerexpired);
printf("失敗次數(shù):%d\n", failed);
printf("成功次數(shù):%d\n", success);
pthread_attr_destroy(&attr);
return 0;
}
北大青鳥(niǎo)APTECH成立于1999年。依托北京大學(xué)優(yōu)質(zhì)雄厚的教育資源和背景,秉承“教育改變生活”的發(fā)展理念,致力于培養(yǎng)中國(guó)IT技能型緊缺人才,是大數(shù)據(jù)專(zhuān)業(yè)的國(guó)家
北大青鳥(niǎo)中博軟件學(xué)院創(chuàng)立于2003年,作為華東區(qū)著名互聯(lián)網(wǎng)學(xué)院和江蘇省首批服務(wù)外包人才培訓(xùn)基地,中博成功培育了近30000名軟件工程師走向高薪崗位,合作企業(yè)超4
中公教育集團(tuán)創(chuàng)建于1999年,經(jīng)過(guò)二十年潛心發(fā)展,已由一家北大畢業(yè)生自主創(chuàng)業(yè)的信息技術(shù)與教育服務(wù)機(jī)構(gòu),發(fā)展為教育服務(wù)業(yè)的綜合性企業(yè)集團(tuán),成為集合面授教學(xué)培訓(xùn)、網(wǎng)
達(dá)內(nèi)教育集團(tuán)成立于2002年,是一家由留學(xué)海歸創(chuàng)辦的高端職業(yè)教育培訓(xùn)機(jī)構(gòu),是中國(guó)一站式人才培養(yǎng)平臺(tái)、一站式人才輸送平臺(tái)。2014年4月3日在美國(guó)成功上市,融資1
浪潮集團(tuán)項(xiàng)目經(jīng)理。精通Java與.NET 技術(shù), 熟練的跨平臺(tái)面向?qū)ο箝_(kāi)發(fā)經(jīng)驗(yàn),技術(shù)功底深厚。 授課風(fēng)格 授課風(fēng)格清新自然、條理清晰、主次分明、重點(diǎn)難點(diǎn)突出、引人入勝。
曾工作于聯(lián)想擔(dān)任系統(tǒng)開(kāi)發(fā)工程師,曾在博彥科技股份有限公司擔(dān)任項(xiàng)目經(jīng)理從事移動(dòng)互聯(lián)網(wǎng)管理及研發(fā)工作,曾創(chuàng)辦藍(lán)懿科技有限責(zé)任公司從事總經(jīng)理職務(wù)負(fù)責(zé)iOS教學(xué)及管理工作。
精通HTML5和CSS3;Javascript及主流js庫(kù),具有快速界面開(kāi)發(fā)的能力,對(duì)瀏覽器兼容性、前端性能優(yōu)化等有深入理解。精通網(wǎng)頁(yè)制作和網(wǎng)頁(yè)游戲開(kāi)發(fā)。
具有10 年的Java 企業(yè)應(yīng)用開(kāi)發(fā)經(jīng)驗(yàn)。曾經(jīng)歷任德國(guó)Software AG 技術(shù)顧問(wèn),美國(guó)Dachieve 系統(tǒng)架構(gòu)師,美國(guó)AngelEngineers Inc. 系統(tǒng)架構(gòu)師。