-
-
Notifications
You must be signed in to change notification settings - Fork 934
/
Copy pathpthread.cpp
153 lines (123 loc) · 5.76 KB
/
pthread.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
//
// This file is part of Easylogging++ samples
//
// Demonstration of multithreaded application using pthread
//
// Compile this program using (if using gcc-c++ or intel or clang++):
// [icpc | g++ | clang++] ./pthread.cpp -o bin/./pthread.cpp.bin -DELPP_THREAD_SAFE -std=c++0x -pthread -Wall -Wextra
//
// Revision: 1.1
// @author abumq (Majid Q.)
//
#include <pthread.h>
#include "easylogging++.h"
INITIALIZE_EASYLOGGINGPP
class MyHandler : public el::LogDispatchCallback {
public:
void handle(const el::LogDispatchData*) {
std::cout << "Test MyHandler " << std::endl;
}
};
struct Args {
const char* thrId;
el::Logger* logger;
}args;
void* write2(void* args){
struct Args* a = (struct Args*)args;
char* threadId = (char*)a->thrId;
el::Logger* logger = (el::Logger*)a->logger;
CLOG(INFO, "default", "network") << "Triggering network log from default and network";
LOG(INFO) << "Writing from different function using macro [Thread #" << threadId << "]";
logger->info("Info log from [Thread #%v]", threadId);
logger->info("Info log");
logger->verbose(2, "Verbose test [Thread #%v]", threadId);
logger->verbose(2, "Verbose test");
CLOG(INFO, "default", "network") << "Triggering network log from default and network";
return NULL;
}
void *write(void* thrId){
char* threadId = (char*)thrId;
// Following line will be logged with every thread
LOG(INFO) << "This standard log is written by [Thread #" << threadId << "]";
// Following line will be logged with every thread only when --v=2 argument
// is provided, i.e, ./bin/multithread_test.cpp.bin --v=2
VLOG(2) << "This is verbose level 2 logging from [Thread #" << threadId << "]";
// Following line will be logged only once from second running thread (which every runs second into
// this line because of interval 2)
LOG_EVERY_N(2, WARNING) << "This will be logged only once from thread who every reaches this line first. Currently running from [Thread #" << threadId << "]";
for (int i = 1; i <= 10; ++i) {
VLOG_IF(true, 2) << "Verbose condition [Thread #" << threadId << "]";
VLOG_EVERY_N(2, 3) << "Verbose level 3 log every 4th time. This is at " << i << " from [Thread #" << threadId << "]";
}
// Following line will be logged once with every thread because of interval 1
LOG_EVERY_N(1, INFO) << "This interval log will be logged with every thread, this one is from [Thread #" << threadId << "]";
LOG_IF(strcmp(threadId, "2") == 0, INFO) << "This log is only for thread 2 and is ran by [Thread #" << threadId << "]";
// Register 5 vague loggers
for (int i = 1; i <= 5; ++i) {
std::stringstream ss;
ss << "logger" << i;
el::Logger* logger = el::Loggers::getLogger(ss.str());
LOG(INFO) << "Registered logger [" << *logger << "] [Thread #" << threadId << "]";
CLOG(INFO, "default", "network") << "Triggering network log from default and network";
}
CLOG(INFO, "logger1") << "Logging using new logger [Thread #" << threadId << "]";
CLOG(INFO, "no-logger") << "THIS SHOULD SAY LOGGER NOT REGISTERED YET [Thread #" << threadId << "]"; // << -- NOTE THIS!
CLOG(INFO, "default", "network") << "Triggering network log from default and network";
el::Logger* logger = el::Loggers::getLogger("default");
logger->info("Info log from [Thread #%v]", threadId);
// Check for log counters positions
for (int i = 1; i <= 50; ++i) {
LOG_EVERY_N(2, INFO) << "Counter pos: " << ELPP_COUNTER_POS << " [Thread #" << threadId << "]";
}
LOG_EVERY_N(2, INFO) << "Counter pos: " << ELPP_COUNTER_POS << " [Thread #" << threadId << "]";
return NULL;
}
// If you wish you can define your own way to get thread ID
const char* getThreadId_CustomVersion(const el::LogMessage*) {
std::stringstream ss;
ss << pthread_self();
return ss.str().c_str();
}
int main(int argc, char** argv)
{
START_EASYLOGGINGPP(argc, argv);
el::Helpers::installLogDispatchCallback<MyHandler>("MyHandler");
// Your thread ID specification
el::CustomFormatSpecifier myThreadIdSpecifier("%mythreadId", getThreadId_CustomVersion);
el::Helpers::installCustomFormatSpecifier(myThreadIdSpecifier);
el::Loggers::addFlag(el::LoggingFlag::MultiLoggerSupport);
// Note your %mythreadId or built-in, both are logged
el::Loggers::reconfigureAllLoggers(el::ConfigurationType::Format, "%datetime %level (%thread | %mythreadId) [%logger] [%func] [%loc] %msg");
el::Loggers::reconfigureAllLoggers(el::Level::Verbose, el::ConfigurationType::Format, "%datetime %level-%vlevel (%thread | %mythreadId) [%logger] [%func] [%loc] %msg");
el::Loggers::getLogger("network");
pthread_t thread1, thread2, thread3, thread4;
// Create independent threads each of which will execute function
pthread_create( &thread1, NULL, write, (void*)"1");
pthread_create( &thread2, NULL, write, (void*)"2");
pthread_create( &thread3, NULL, write, (void*)"3");
el::Logger* logger = el::Loggers::getLogger("default");
args.thrId = "4";
args.logger = logger;
pthread_create( &thread4, NULL, write2, (void*)&args);
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
pthread_join(thread3, NULL);
pthread_join(thread4, NULL);
#if 0 // Change this to 1 for some serious multiple threads
int i = 5; // Last one we created was 4 so we dont want to confuse
const int max = i + 500;
for (; i <= max; ++i) {
pthread_t thread;
std::string s = std::to_string(static_cast<long long>(i));
if (i % 2 == 0)
pthread_create( &thread, NULL, write, (void*)s.c_str());
else {
args.thrId = s.c_str();
args.logger = logger;
pthread_create( &thread, NULL, write2, (void*)&args);
}
pthread_join(thread, NULL);
}
#endif
exit(0);
}