Ubuntu 13.04,g++4.7,Pthread实现多线程模拟实现下载进度条:
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#include <iostream>
#include <sys/times.h>
//pthread实现多线程:一个线程模拟下载,一个线程读取当前进度
//线程用的参数,用于传递参数
struct Args {
int* length_ptr;
pthread_rwlock_t* rwlock_ptr;
};
void* download(void* args) {
//printf("args address = %p\n", args);
Args args_object = *(Args*)args;
Args* a = &args_object;
printf("start_download OK\n");
printf("before while length = %d\n", *a->length_ptr);
//printf("before while length = %p\n", a->length_ptr);
while(*a->length_ptr > 0) {
//printf("in while length = %d\n", *a->length_ptr);
//printf("in while length =%p\n", a->length_ptr);
int number = rand() % 100;
pthread_rwlock_wrlock(a->rwlock_ptr);
*a->length_ptr -= number;
printf("after length - %d; length = %d\n", number, *a->length_ptr);
pthread_rwlock_unlock(a->rwlock_ptr);
sleep(1);
}
return NULL;
}
class Ftp {
private:
int length;
static const int LENGTH = 10000000;
pthread_rwlock_t rwlock;
public:
Ftp() {
length = LENGTH;
int err = pthread_rwlock_init(&rwlock, NULL);
if(err != 0) {
//error
fprintf(stderr, "Error!\n");
}
}
~Ftp() {
pthread_rwlock_destroy(&rwlock);
}
pthread_t start_download() {
pthread_t thread_id;
Args* a = new Args();//线程传递参数放在栈上有问题,所以只能new一个
a->length_ptr = &length;
a->rwlock_ptr = &rwlock;
//printf("in start_download and before pthread_create: length = %d\n", *a->length_ptr);
//printf("in start_download and before pthread_create: length = %p\n", a->length_ptr);
//printf("in start_download(): args address = %p\n", a);
int err = pthread_create(&thread_id, NULL, download, a);
//printf("in start_download and before pthread_create: length = %p\n", a->length_ptr);
if(err != 0) {
//error
fprintf(stderr, "Error!\n");
return -1;
}
return thread_id;
}
int get_length() {
int len = -1;
pthread_rwlock_rdlock(&rwlock);
len = length;
pthread_rwlock_unlock(&rwlock);
return len;
}
};
void* test_thread_fun(void* args) {
Ftp* ftp_ptr = static_cast<Ftp*>(args);//这个线程参数也是一样,只不过因为有pthread_join保证了main中的ftp没有析构
while(ftp_ptr->get_length() > 0 ) {
printf("read length from test_thread_fun: length = %d\n", ftp_ptr->get_length());
//sleep(rand() % 5);
sleep(1);
}
}
int main() {
srand(0);
//There is still a lot to do for this program
Ftp ftp;
pthread_t thread_id = ftp.start_download();
pthread_t id;
//test thread
int err = pthread_create(&id, NULL, test_thread_fun, &ftp);
if(err != 0) {
//error
fprintf(stderr, "Error!\n");
return -1;
}
//wait thread_id exit
pthread_join(thread_id, NULL);
return 0;
}