int main(int argc, char **argv) { pthread_t tid[NUMT]; int i; int error; (void)argc; /* we don't use any arguments in this example */ (void)argv; /* Must initialize libcurl before any threads are started */ curl_global_init(CURL_GLOBAL_ALL); init_locks(); for(i=0; i< NUMT; i++) { error = pthread_create(&tid[i], NULL, /* default attributes please */ pull_one_url, (void *)urls[i]); if(0 != error) fprintf(stderr, "Couldn't run thread number %d, errno %d\n", i, error); else fprintf(stderr, "Thread %d, gets %s\n", i, urls[i]); } /* now wait for all threads to terminate */ for(i=0; i< NUMT; i++) { error = pthread_join(tid[i], NULL); fprintf(stderr, "Thread %d terminated\n", i); } kill_locks(); return 0; }
void KICAD_CURL::Cleanup() { /* Calling MUTLOCK() from a static destructor will typically be bad, since the s_lock may already have been statically destroyed itself leading to a boost exception. (Remember C++ does not provide certain sequencing of static destructor invocation.) To prevent this we test s_initialized twice, which ensures that the MUTLOCK is only instantiated on the first call, which should be from PGM_BASE::destroy() which is first called earlier than static destruction. Then when called again from the actual PGM_BASE::~PGM_BASE() function, MUTLOCK will not be instantiated because s_initialized will be false. */ if( s_initialized ) { MUTLOCK lock( s_lock ); if( s_initialized ) { curl_global_cleanup(); kill_locks(); atexit( &at_terminate ); s_initialized = false; } } }
int main(int argc, char **argv) { pthread_t tid[NUMT]; int error; curl_global_init(CURL_GLOBAL_ALL); init_locks(); for (int i = 0; i < NUMT; i++) { error = pthread_create(&tid[i], NULL, pull_one_url, (void *)urls[i]); if (0 != error) fprintf(stderr, "Couldn't run thread number %d, errno %d\n", i, error); else fprintf(stderr, "Thread %d, gets %s\n", i, urls[i]); } for (int i = 0; i < NUMT; i++) { error = pthread_join(tid[i], NULL); fprintf(stderr, "Thread %d terminated\n", i); } kill_locks(); return 0; }
int main(int argc, char **argv) { memset(&global_info, 0, sizeof(global_info_t)); char *url = http_url; global_info.round = 1; int opt; while ((opt = getopt(argc, argv, "w:t:r:hs")) != -1) { switch (opt) { case 'w': global_info.work_num = atoi(optarg); break; case 't': global_info.thread_num = atoi(optarg); break; case 'r': global_info.round = atoi(optarg); break; case 's': url = https_url; break; case 'h': default: show_help(); return EXIT_SUCCESS; } } if (global_info.work_num == 0 || global_info.thread_num == 0) { show_help(); return EXIT_FAILURE; } setsignal(SIGINT, _sig_int); setsignal(SIGTERM, _sig_int); printf("get work num: %u, thread num: %u\n", global_info.work_num, global_info.thread_num); thread_info_t *thread_list = calloc(global_info.thread_num, sizeof(thread_info_t)); if (thread_list == NULL) { printf("alloc threads error\n"); return EXIT_FAILURE; } global_info.work_list = calloc(global_info.work_num, sizeof(work_info_t *)); if (global_info.work_list == NULL) { printf("alloc work_list error\n"); return EXIT_FAILURE; } int idx = 0; for (idx = 0; idx < global_info.work_num; ++idx) { global_info.work_list[idx] = calloc(1, sizeof(work_info_t)); if (global_info.work_list[idx] == NULL) { printf("alloc work_list %u error\n", idx); return EXIT_FAILURE; } global_info.work_list[idx]->url = url; global_info.work_list[idx]->idx = idx; } /* Must initialize libcurl before any threads are started */ curl_global_init(CURL_GLOBAL_ALL); init_locks(); TS_INIT(); mutexlock_init(global_info.rmtx); mutexlock_init(global_info.wmtx); TS_DECLARE(perf); for (idx = 0; idx < global_info.thread_num; ++idx) { thread_list[idx].global_info = &global_info; thread_list[idx].curl = curl_easy_init(); thread_list[idx].multi_handle = curl_multi_init(); if (thread_list[idx].curl == NULL || thread_list[idx].multi_handle == NULL) { printf("error when curl init\n"); return EXIT_FAILURE; } //curl_easy_setopt(thread_list[idx].curl, CURLOPT_FORBID_REUSE, 1L); curl_easy_setopt(thread_list[idx].curl, CURLOPT_NOSIGNAL, 1L); if (url == https_url) { curl_easy_setopt(thread_list[idx].curl, CURLOPT_SSL_VERIFYPEER, 0L); curl_easy_setopt(thread_list[idx].curl, CURLOPT_SSL_VERIFYHOST, 0L); } thread_list[idx].idx = idx; set_share_handle(thread_list[idx].curl); } int error; TS_BEGIN(perf); for (idx = 0; idx < global_info.thread_num; ++idx) { error = pthread_create(&(thread_list[idx].tid), NULL, /* default attributes please */ pull_one_url, (void *) & (thread_list[idx])); if (0 != error) { fprintf(stderr, "Couldn't run thread number %d, errno %d\n", idx, error); return EXIT_FAILURE; } } /* now wait for all threads to terminate */ for (idx = 0; idx < global_info.thread_num; idx++) { error = pthread_join(thread_list[idx].tid, NULL); //printf("[%u:%lu]Thread %d terminated\n", idx, time(NULL), idx); } TS_END(perf); for (idx = 0; idx < global_info.thread_num; idx++) { curl_easy_cleanup(thread_list[idx].curl); curl_multi_cleanup(thread_list[idx].multi_handle); } free(thread_list); unsigned long total_length = 0; for (idx = 0; idx < global_info.work_num; idx++) { if (global_info.work_list[idx]) { if (global_info.work_list[idx]->status == STAT_DONE) { total_length += global_info.work_list[idx]->data_len; } free(global_info.work_list[idx]); } } free(global_info.work_list); printf("RATE: worknum:%u total_length:%lu total_ms_diff:%lu, %.1fK\n", global_info.work_num, total_length, TS_MSDIFF(perf), (double)(total_length) / (double)(TS_MSDIFF(perf))); kill_locks(); curl_global_cleanup(); return EXIT_SUCCESS; }