条件变量的用法和封装

对条件变量的用法的说明可以见这里,http://www.wuzesheng.com/?p=1668,写的不错,看一个裸写的无封装的用法如下:

#include <stdio.h>
#include <sys/time.h>
#include <time.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <queue>
#include <string>

#define  _PRINTF_(format, ...) printf("[%s][%05ld] " format " [%s::%s::%d]\n", getdatetimestr(), syscall(__NR_gettid), ##__VA_ARGS__, __FILE__, __FUNCTION__, __LINE__)

char* getdatetimestr() {
    static char datetimestr[32] = {0};
    static time_t last_update_time = 0;
    struct timeval tv = {0};
    gettimeofday(&tv, NULL);
    time_t nowtime = tv.tv_sec;
    if (nowtime != last_update_time) {
        last_update_time = nowtime;
        struct tm nowtm = {0};
        localtime_r(&nowtime, &nowtm);
        strftime(datetimestr, sizeof(datetimestr), "%Y-%m-%d %H:%M:%S", &nowtm);
    }
    snprintf(datetimestr+19, sizeof(datetimestr)-19, ".%06ld", tv.tv_usec);
    return datetimestr;
}

std::queue<std::string> task_queue;
pthread_mutex_t mutex_t = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond_t = PTHREAD_COND_INITIALIZER;

void* thread_func1(void*) {
	_PRINTF_("producer");
	while (1) {
		//int sleep_sec = rand() % 5;
		//_PRINTF_("sleep %d sec", sleep_sec);
		//sleep(sleep_sec);
		
		_PRINTF_("waiting for mutex_t");
		pthread_mutex_lock(&mutex_t);
		std::string datetimestr = getdatetimestr();
		task_queue.push(datetimestr);
		_PRINTF_("put %s queue size %lu", datetimestr.c_str(), task_queue.size());
		pthread_cond_signal(&cond_t);
		pthread_mutex_unlock(&mutex_t);
	}	
	return NULL;
}

void* thread_func2(void* args) {
	char* indent = (char*)args;
	_PRINTF_("%s" "customer", indent);
	while (1) {
		//int sleep_sec = rand() % 5;
		//_PRINTF_("%s" "sleep %d sec", indent, sleep_sec);
		//sleep(sleep_sec);		
		
		_PRINTF_("%s" "waiting for mutex_t", indent);
		pthread_mutex_lock(&mutex_t);
		while (task_queue.empty()) {
			pthread_cond_wait(&cond_t, &mutex_t);
		}
		std::string datetimestr = task_queue.front();
		_PRINTF_("%s" "got %s queue size %lu", indent, datetimestr.c_str(), task_queue.size());
		task_queue.pop();
		pthread_mutex_unlock(&mutex_t);
	}	
	return NULL;
}

int main() {
	_PRINTF_("start");
	
	srand(time(NULL));
	
	pthread_t thread_t1 = {0};
	if (pthread_create(&thread_t1, NULL, thread_func1, NULL) != 0) {
		_PRINTF_("%m");
		return -1;
	}
	_PRINTF_("create thread 1 success");
	
	pthread_t thread_t21 = {0};
	char* indent21 = "\t";
	if (pthread_create(&thread_t21, NULL, thread_func2, (void*)indent21) != 0) {
		_PRINTF_("%m");
		return -1;
	}
	_PRINTF_("create thread 2 success");	
	
	pthread_t thread_t22 = {0};
	char* indent22 = "\t\t";
	if (pthread_create(&thread_t22, NULL, thread_func2, (void*)indent22) != 0) {
		_PRINTF_("%m");
		return -1;
	}
	_PRINTF_("create thread 22 success");	
	
	pthread_t thread_t23 = {0};
	char* indent23 = "\t\t\t";
	if (pthread_create(&thread_t23, NULL, thread_func2, (void*)indent23) != 0) {
		_PRINTF_("%m");
		return -1;
	}
	_PRINTF_("create thread 23 success");
	
	pthread_join(thread_t1, NULL);
	pthread_join(thread_t21, NULL);
	pthread_join(thread_t22, NULL);
	pthread_join(thread_t23, NULL);
	
	_PRINTF_("end");
	
	return 0;
}

Leave a Reply

Your email address will not be published. Required fields are marked *