pthread_mutex_unlock(&_mutex);
}
T pop() {
data_event.wait();
pthread_mutex_lock(&_mutex);
T res = data_queue.front();
data_queue.pop();
pthread_mutex_unlock(&_mutex);
return res;
}
private:
std::queue<T> data_queue;
event data_event;
pthread_mutex_t _mutex;
};
ΠΠ° ΠΏΠ΅ΡΠ²ΡΠΉ Π²Π·Π³Π»ΡΠ΄ Π·Π°Π΄Π°ΡΠ° ΠΎΡΠ΅Π²ΠΈΠ΄Π½Π°: Π½Π°Π΄ΠΎ Π½Π΅ Π΄ΠΎΠΏΡΡΡΠΈΡΡ ΠΎΠ΄Π½ΠΎΠ²ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΠ³ΠΎ ΠΈΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ Π΄Π²ΡΡ ΡΡΠ°ΡΡΠΊΠΎΠ² ΠΊΠΎΠ΄Π°. ΠΠΎΡΠ΅ΠΌΡ ΠΆΠ΅ Π½Π΅ Π²ΠΎΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡΡΡ ΡΠ΅ΠΌΠ°ΡΠΎΡΠΎΠΌ, ΠΊΠ°ΠΊ ΠΌΡ ΠΎΠΏΠΈΡΡΠ²Π°Π»ΠΈ, ΠΊΠΎΠ³Π΄Π° ΡΠ°ΡΡΠΊΠ°Π·ΡΠ²Π°Π»ΠΈ ΠΎ ΡΠΏΠΎΡΠΎΠ±Π°Ρ Π΅Π³ΠΎ ΠΏΡΠΈΠΌΠ΅Π½Π΅Π½ΠΈΡ? ΠΠ΅Π»ΠΎ Π² ΡΠΎΠΌ, ΡΡΠΎ ΠΌΡ Ρ ΠΎΡΠ΅Π»ΠΈ ΠΏΠΎΠ»ΡΡΠΈΡΡ ΡΠ½ΠΈΠ²Π΅ΡΡΠ°Π»ΡΠ½ΠΎΠ΅ ΡΡΠ΅Π΄ΡΡΠ²ΠΎ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΠΈ Π΄Π°Π½Π½ΡΡ ΠΌΠ΅ΠΆΠ΄Ρ ΠΏΠΎΡΠΎΠΊΠ°ΠΌΠΈ, Π½Π΅ Π·Π°Π²ΠΈΡΡΡΠ΅Π΅ ΠΎΡ Π΄ΠΎΠΏΡΡΠ΅Π½ΠΈΠΉ ΠΎ ΠΏΡΠΈΠΎΡΠΈΡΠ΅ΡΠ°Ρ ΠΏΠΎΡΠΎΠΊΠΎΠ² ΠΈ ΡΡΠ΅ΠΏΠ΅Π½ΠΈ ΠΈΡ Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡΠΈ. ΠΠΎΠ³Π΄Π° ΠΌΡ ΡΡΡΠΎΠΈΠΌ ΡΠΈΡΡΠ΅ΠΌΡ ΡΠ΅Π°Π»ΡΠ½ΠΎΠ³ΠΎ Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ, Π²ΠΎΠΏΡΠΎΡ Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ³ΠΎ Π½Π΅ΡΠ²Π½ΠΎΠ³ΠΎ Π²Π»ΠΈΡΠ½ΠΈΡ ΡΠ°Π·Π½ΡΡ ΠΏΠΎΡΠΎΠΊΠΎΠ² Π½Π° Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ Π΄ΡΡΠ³ Π΄ΡΡΠ³Π° ΡΡΠ°Π½ΠΎΠ²ΠΈΡΡΡ ΠΎΡΠ΅Π½Ρ Π²Π°ΠΆΠ½ΡΠΌ. ΠΡ ΡΠΆΠ΅ Π½Π΅ΠΎΠ΄Π½ΠΎΠΊΡΠ°ΡΠ½ΠΎ ΡΠΏΠΎΠΌΠΈΠ½Π°Π»ΠΈ ΡΡΡΠ΅ΠΊΡ ΠΈΠ½Π²Π΅ΡΡΠΈΠΈ ΠΏΡΠΈΠΎΡΠΈΡΠ΅ΡΠΎΠ² ΠΈ ΡΠ΅ ΡΠΏΠΎΡΠΎΠ±Ρ, ΠΊΠΎΡΠΎΡΡΠΌΠΈ ΠΌΠΎΠΆΠ½ΠΎ Π΅Π΅ ΠΈΠ·Π±Π΅ΠΆΠ°ΡΡ, ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡ ΠΌΡΡΡΠ΅ΠΊΡ Π΄Π»Ρ Π·Π°ΡΠΈΡΡ ΡΠΊΡΠΊΠ»ΡΠ·ΠΈΠ²Π½ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌΠΎΠ³ΠΎ ΠΊΠΎΠ΄Π°.
Π‘ΡΠ°Π²Π½Π΅Π½ΠΈΠ΅ ΠΈ ΡΡΡΠ΅ΠΊΡΠΈΠ²Π½ΠΎΡΡΡ
Π ΡΡΠΎΠΌ ΠΌΠ΅ΡΡΠ΅ Π²ΡΠ΅ΠΌΠ΅Π½Π½ΠΎ ΠΏΡΠ΅ΡΠ²Π΅ΠΌ Π½Π°ΡΠ΅ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΠ΅Π»ΡΠ½ΠΎΠ΅ ΠΏΠΎΠ²Π΅ΡΡΠ²ΠΎΠ²Π°Π½ΠΈΠ΅: ΠΌΡ Π·Π°ΠΊΠΎΠ½ΡΠΈΠ»ΠΈ ΡΠ°ΡΡΠΌΠΎΡΡΠ΅Π½ΠΈΠ΅ Π΄Π²ΡΡ Π½Π°ΠΈΠ±ΠΎΠ»Π΅Π΅ ΠΈΠ·Π²Π΅ΡΡΠ½ΡΡ , Π²Π°ΠΆΠ½ΡΡ ΠΈ ΠΏΡΠΈΠΌΠ΅Π½ΡΠ΅ΠΌΡΡ ΠΏΡΠΈΠΌΠΈΡΠΈΠ²ΠΎΠ² ΡΠΈΠ½Ρ ΡΠΎΠ½ΠΈΠ·Π°ΡΠΈΠΈ β ΡΠ΅ΠΌΠ°ΡΠΎΡΠ° ΠΈ ΠΌΡΡΡΠ΅ΠΊΡΠ°. Π’Π΅ΠΏΠ΅ΡΡ ΡΠ΄Π΅Π»Π°Π΅ΠΌ ΠΊΠΎΡΠΎΡΠΊΡΡ ΠΎΡΡΠ°Π½ΠΎΠ²ΠΊΡ ΠΈ ΠΏΡΠΎΠ²Π΅Π΄Π΅ΠΌ ΠΈΡ Π²Π·Π°ΠΈΠΌΠ½ΠΎΠ΅ ΡΡΠ°Π²Π½Π΅Π½ΠΈΠ΅, Π° ΡΠ°ΠΊΠΆΠ΅ ΠΏΠΎΠΏΡΠΎΠ±ΡΠ΅ΠΌ Π½Π° ΠΏΡΠΈΠΌΠ΅ΡΠ°Ρ ΠΎΡΠ΅Π½ΠΈΡΡ Π·Π°ΡΡΠ°ΡΡ ΠΏΡΠΎΡΠ΅ΡΡΠΎΡΠ½ΠΎΠΉ ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡΠ΅Π»ΡΠ½ΠΎΡΡΠΈ, ΡΡΠ΅Π±ΡΠ΅ΠΌΡΠ΅ ΡΡΠΈΠΌΠΈ ΠΌΠ΅Ρ Π°Π½ΠΈΠ·ΠΌΠ°ΠΌΠΈ.
ΠΠ΅Π»ΠΎ Π² ΡΠΎΠΌ, ΡΡΠΎ Π½Π° ΠΏΠ΅ΡΠ²ΡΠΉ Π²Π·Π³Π»ΡΠ΄ ΡΡΠΈ Π΄Π²Π° ΠΌΠ΅Ρ Π°Π½ΠΈΠ·ΠΌΠ° Π² Π²ΡΡΡΠ΅ΠΉ ΡΡΠ΅ΠΏΠ΅Π½ΠΈ ΠΏΠΎΠ΄ΠΎΠ±Π½Ρ, ΠΎΡΠΎΠ±Π΅Π½Π½ΠΎ Π΅ΡΠ»ΠΈ ΡΠ΅ΡΡ Π·Π°Ρ ΠΎΠ΄ΠΈΡ ΠΎ Π±ΠΈΠ½Π°ΡΠ½ΠΎΠΌ ΡΠ΅ΠΌΠ°ΡΠΎΡΠ΅, ΠΏΡΠΈΠ½ΠΈΠΌΠ°ΡΡΠ΅ΠΌ Π·Π½Π°ΡΠ΅Π½ΠΈΡ ΡΡΠ΅ΡΡΠΈΠΊΠ° 0 Π»ΠΈΠ±ΠΎ 1. ΠΠ°ΡΡΠΎΠ»ΡΠΊΠΎ ΠΏΠΎΠ΄ΠΎΠ±Π½Ρ, ΡΡΠΎ ΠΈ Π² ΠΎΠ±ΡΡΠΆΠ΄Π΅Π½ΠΈΡΡ , ΠΈ Π΄Π°ΠΆΠ΅ Π² Π½Π΅ΡΠΏΠ΅ΡΠΈΠ°Π»ΡΠ½ΠΎΠΉ Π»ΠΈΡΠ΅ΡΠ°ΡΡΡΠ΅ ΠΌΠΎΠΆΠ½ΠΎ Π²ΡΡΡΠ΅ΡΠΈΡΡ ΡΡΠ²Π΅ΡΠΆΠ΄Π΅Π½ΠΈΡ, ΡΡΠΎ ΡΡΠΎ Β«ΠΎΠ΄Π½ΠΎ ΠΈ ΡΠΎ ΠΆΠ΅Β». Π‘Π΅ΠΉΡΠ°Ρ ΠΌΡ ΡΠ²ΠΈΠ΄ΠΈΠΌ, ΡΡΠΎ ΡΡΠΈ Π΄Π²Π° ΡΡ ΠΎΠ΄Π½ΡΡ ΠΌΠ΅Ρ Π°Π½ΠΈΠ·ΠΌΠ° ΡΠ°Π·Π»ΠΈΡΠ°ΡΡΡΡ Π²ΡΠ΅ΠΌ: ΠΈ Π·Π°ΡΡΠ°ΡΠ°ΠΌΠΈ ΠΏΡΠΎΡΠ΅ΡΡΠΎΡΠ½ΠΎΠ³ΠΎ Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ Π½Π° ΠΈΡ ΠΎΠ±ΡΠ»ΡΠΆΠΈΠ²Π°Π½ΠΈΠ΅, ΠΈ ΡΠ΅Π»ΡΠΌΠΈ ΠΈ Π·Π°Π΄Π°ΡΠ°ΠΌΠΈ, ΠΊΠΎΡΠΎΡΡΠ΅ ΠΎΠ½ΠΈ ΠΏΡΠΈΠ·Π²Π°Π½Ρ ΡΠ΅ΡΠ°ΡΡ, ΠΈ Π²ΡΠ΅ΠΌΠ΅Π½Π΅ΠΌ ΠΆΠΈΠ·Π½ΠΈβ¦ ΠΠ°ΡΠ½Π΅ΠΌ Ρ ΠΏΡΠΎΡΡΠΎΠΉ ΠΎΡΠ΅Π½ΠΊΠΈ Π·Π°ΡΡΠ°Ρ ΠΏΡΠΎΡΠ΅ΡΡΠΎΡΠ½ΠΎΠ³ΠΎ Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ Π½Π° ΠΎΠ±ΡΠ»ΡΠΆΠΈΠ²Π°Π½ΠΈΠ΅ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΠΈΠ· ΠΌΠ΅Ρ Π°Π½ΠΈΠ·ΠΌΠΎΠ², ΠΏΠΎΡΠ»Π΅ ΡΠ΅Π³ΠΎ ΠΎΡΡΠ°Π»ΡΠ½ΡΠ΅ ΡΠ°Π·Π»ΠΈΡΠΈΡ ΡΡΠ°Π½ΡΡ Π½Π°ΠΌ Π½Π°ΠΌΠ½ΠΎΠ³ΠΎ ΠΏΠΎΠ½ΡΡΠ½Π΅Π΅.
ΠΠ»Ρ ΠΏΡΠΎΠ²Π΅Π΄Π΅Π½ΠΈΡ ΡΠ°ΠΊΠΈΡ ΠΎΡΠ΅Π½ΠΎΠΊ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌ ΡΠΆΠ΅ ΠΏΡΠΈΠΌΠ΅Π½ΡΠ²ΡΡΡΡΡ Π½Π°ΠΌΠΈ ΡΡ Π΅ΠΌΡ Β«ΡΠΈΠΌΠΌΠ΅ΡΡΠΈΡΠ½ΡΡ Β» ΡΠ΅ΡΡΠΎΠ². ΠΠΎΡΠ΅ΠΌΡ ΠΈΠΌΠ΅Π½Π½ΠΎ ΠΈΡ ? ΠΠ°, Π·Π΄Π΅ΡΡ Π½Π°ΠΌ Π½Π΅ ΡΡΠ΅Π±ΡΡΡΡΡ Π² ΡΠ²Π½ΠΎΠΌ Π²ΠΈΠ΄Π΅ ΠΎΠ±ΠΌΠ΅Π½Π½ΡΠ΅ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ ΠΏΠΎΡΠΎΠΊΠΎΠ², Π½ΠΎ Π²ΠΎΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌΡΡ Β«ΡΠΈΠΌΠΌΠ΅ΡΡΠΈΡΠ½ΡΠΌΠΈΒ» ΡΠ΅ΡΡΠ°ΠΌΠΈ ΠΏΡΠΎΡΡΠΎ Π² ΡΠΈΠ»Ρ ΠΌΠΈΠ½ΠΈΠΌΠ°Π»ΡΠ½ΡΡ ΠΏΠ΅ΡΠ΅Π΄Π΅Π»ΠΎΠΊ ΡΠΎΠ³ΠΎ, ΡΡΠΎ ΡΠΆΠ΅ Π±ΡΠ»ΠΎ Π½Π°ΠΏΠΈΡΠ°Π½ΠΎ ΡΠ°Π½Π΅Π΅. ΠΡΠ°ΠΊ, ΠΏΠ΅ΡΠ²ΡΠΉ Π²Π°ΡΠΈΠ°Π½Ρ ΡΠ΅ΡΡΠ° Π΄Π»Ρ ΠΌΡΡΡΠ΅ΠΊΡΠ° (ΡΠ°ΠΉΠ» sy20m.cc):
Π‘ΠΊΠΎΡΠΎΡΡΠ½ΡΠ΅ ΠΏΠΎΠΊΠ°Π·Π°ΡΠ΅Π»ΠΈ ΠΌΡΡΡΠ΅ΠΊΡΠ°unsigned long N = 1000;
static pthread_barrier_t bstart;
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
static bool debug = false;
static char* str;
static volatile int ind = 0;
void* threadfunc(void* data) {
pthread_barrier_wait(&bstart);
unsigned long i = 0;
char tid[8];
sprintf(tid, "%d", pthread_self());
uint64_t t = 0, t1;
while (i++ != N) {
t1 = ClockCycles();
pthread_mutex_lock(&mutex);
if (debug) str[ind++] = *tid;
pthread_mutex_unlock(&mutex);
t += ClockCycles() - t1;
sched_yield();
}
cout << pthread_self() << "\t: cycles - "
<< t << ", on mutex - " << t / N << endl;
return NULL;
}
int main(int argc, char *argv[]) {
int opt, val;
while ((opt = getopt(argc, argv, "n,v")) != -1) {
switch (opt) {
case 'n':
if (sscanf(optarg, "%i", &val) != 1)
cout << "parse command line error" << endl, exit(EXIT_FAILURE);
if (val > 0) N = val;
break;
case 'v':
debug = true;
break;
default:
exit(EXIT_FAILURE);
}
}
if (debug) str = new char[2 * N + 1];
const int T = 2;
pthread_t tid[T];
if (pthread_barrier_init(&bstart, NULL, T) != EOK)
perror("barrier init"), exit(EXIT_FAILURE);
for (int i = 0; i < T; i++)
if (pthread_create(tid + i, NULL, threadfunc, NULL) != EOK)
perror("thread create"), exit(EXIT_FAILURE);
for (int i = 0; i < T; i++)
pthread_join(tid[i], NULL);
if (debug) {
str[ind] = '\0';
cout << str << endl;
delete [] str;
}
exit(EXIT_SUCCESS);
}
Π Π΅Π·ΡΠ»ΡΡΠ°ΡΡ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ ΡΡΠΎΠ³ΠΎ ΡΠ΅ΡΡΠ°:
# sy20m -n100000
3 : cycles - 14644442, on mutex - 146
2 : cycles - 14614219; on mutex - 146
# sy20m -n1000000
3 : cycles - 146505047; on mutex - 146
2 : cycles - 146388673; on mutex - 146
ΠΠΎΠ΄ΠΈΡΠΈΡΠΈΡΡΠ΅ΠΌ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ, ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡ Π²ΠΌΠ΅ΡΡΠΎ ΠΌΡΡΡΠ΅ΠΊΡΠ° Π½Π΅ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½Π½ΡΠΉ Π±ΠΈΠ½Π°ΡΠ½ΡΠΉ ΡΠ΅ΠΌΠ°ΡΠΎΡ. ΠΠ»Ρ ΡΠΎΠ³ΠΎ ΡΡΠΎΠ±Ρ Π½Π΅ Π·Π°Π³ΡΠΎΠΌΠΎΠΆΠ΄Π°ΡΡ ΡΠ΅ΠΊΡΡ ΠΏΡΠ°ΠΊΡΠΈΡΠ΅ΡΠΊΠΈ ΡΠ΅ΠΌ ΠΆΠ΅ ΠΊΠΎΠ΄ΠΎΠΌ, ΠΏΠ΅ΡΠ΅ΡΠΈΡΠ»ΠΈΠΌ ΡΠΎΠ»ΡΠΊΠΎ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΡΠ΅ ΠΏΡΠΈ ΡΡΠΎΠΌ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΡ (ΡΠ°ΠΉΠ» sy20s.cc):
1. ΠΠΌΠ΅ΡΡΠΎ ΠΌΡΡΡΠ΅ΠΊΡΠ° ΠΎΠ±ΡΡΠ²Π»ΡΠ΅ΠΌ Π½Π΅ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½Π½ΡΠΉ ΡΠ΅ΠΌΠ°ΡΠΎΡ, Π° ΡΡΠ°ΡΠΈΡΠ΅ΡΠΊΠ°Ρ ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·Π°ΡΠΈΡ ΠΌΡΡΡΠ΅ΠΊΡΠ° Π·Π°ΠΌΠ΅Π½ΡΠ΅ΡΡΡ Π½Π° ΠΎΠΏΠ΅ΡΠ°ΡΠΎΡ (Π² ΡΠ΅Π»Π΅ Π³Π»Π°Π²Π½ΠΎΠΉ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ) Π΄ΠΈΠ½Π°ΠΌΠΈΡΠ΅ΡΠΊΠΎΠΉ ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·Π°ΡΠΈΠΈ ΡΠ΅ΠΌΠ°ΡΠΎΡΠ° Ρ ΠΏΡΠΈΡΠ²ΠΎΠ΅Π½ΠΈΠ΅ΠΌ Π΅ΠΌΡ Π½Π°ΡΠ°Π»ΡΠ½ΠΎΠ³ΠΎ Π·Π½Π°ΡΠ΅Π½ΠΈΡ 1:
static sem_t sem;
...
if (sem_init(&sem, 0, 1) != 0)
perror("semaphore init"), exit(EXIT_FAILURE);
2. Π€ΡΠ½ΠΊΡΠΈΡ ΠΏΠΎΡΠΎΠΊΠ° ΠΏΡΠΈΠ½ΠΈΠΌΠ°Π΅Ρ Π²ΠΈΠ΄:
void* threadfunc(void* data) {
...
while (i++ != N) {
t1 = ClockCycles();
sem_wait(&sem);
if (debug) str[ind++] = *tid;
sem_post(&sem);
t += ClockCycles() - t1;
sched_yield();
}
...
}
Π ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΠ΅ ΠΈΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ Π½Π° ΡΡΠΎΡ ΡΠ°Π· ΠΌΡ ΠΏΠΎΠ»ΡΡΠΈΠΌ:
# sy20s -n100000
3 : cycles - 87048886; on semaphore - 870
2 : cycles - 87077787; on semaphore - 870
# sy20s -n1000000
3 : cycles - 869638168; on semaphore β 869
2 : cycles - 868725494, on semaphore - 868
ΠΠ΅Π»Π°Π΅ΠΌ ΠΏΠΎΡΠ»Π΅Π΄Π½ΡΡ ΠΌΠΎΠ΄ΠΈΡΠΈΠΊΠ°ΡΠΈΡ Π² ΡΡΠΎΠΉ Π³ΡΡΠΏΠΏΠ΅ ΡΠ΅ΡΡΠΎΠ², ΡΠ΅ΠΏΠ΅ΡΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌ ΡΠΏΠ΅ΡΠΈΡΠΈΠΊΡ ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½Π½ΠΎΠ³ΠΎ ΡΠ΅ΠΌΠ°ΡΠΎΡΠ° (ΡΠ°ΠΉΠ» sy20n.cc):
1. ΠΠΌΠ΅ΡΡΠΎ ΠΎΠΏΠ΅ΡΠ°ΡΠΎΡΠ° Π΄ΠΈΠ½Π°ΠΌΠΈΡΠ΅ΡΠΊΠΎΠΉ ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·Π°ΡΠΈΠΈ Π½Π΅ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½Π½ΠΎΠ³ΠΎ ΡΠ΅ΠΌΠ°ΡΠΎΡΠ° ΠΌΡ ΡΠ΅ΠΏΠ΅ΡΡ Π΄ΠΎΠ»ΠΆΠ½Ρ ΡΠΎΠ·Π΄Π°ΡΡ ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½Π½ΡΠΉ ΡΠ΅ΠΌΠ°ΡΠΎΡ:
static sem_t* sem;
...
const char semname[] = "/duble";
if ((sem = sem_open(semname, O_CREAT, S_IRWX0, 1)) == SEM_FAILED)
perror("semaphore init"), exit(EXIT_FAILURE);
ΠΡΠΈΠΌΠ΅ΡΠ°Π½ΠΈΠ΅ΠΠΎΡΠ»Π΅Π΄Π½ΠΈΠΉ ΠΎΠΏΠ΅ΡΠ°ΡΠΎΡ Π·Π°ΡΠ»ΡΠΆΠΈΠ²Π°Π΅Ρ ΠΎΡΠ΄Π΅Π»ΡΠ½ΠΎΠ³ΠΎ ΠΊΠΎΠΌΠΌΠ΅Π½ΡΠ°ΡΠΈΡ. Π’Π΅Ρ Π½ΠΈΡΠ΅ΡΠΊΠ°Ρ Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΠ°ΡΠΈΡ ΡΡΠ²Π΅ΡΠΆΠ΄Π°Π΅Ρ, ΡΡΠΎ ΡΡΠ½ΠΊΡΠΈΡ sem_open(), Π½ΠΎΡΠΌΠ°Π»ΡΠ½ΠΎ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°ΡΡΠ°Ρ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ ΡΠΎΠ·Π΄Π°Π½Π½ΠΎΠ³ΠΎ Π΄Π΅ΡΠΊΡΠΈΠΏΡΠΎΡΠ° ΡΠ΅ΠΌΠ°ΡΠΎΡΠ° ΡΠΈΠΏΠ° sem_t, Π² ΡΠ»ΡΡΠ°Π΅ ΠΎΡΠΈΠ±ΠΊΠΈ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅Ρ -1 (ΡΠ°ΠΊ Π±ΡΠ»ΠΎ Π·Π°ΠΏΠΈΡΠ°Π½ΠΎ ΠΈ Π² ΡΠ°ΠΌΡΡ ΡΠ°Π½Π½ΠΈΡ ΡΠ΅Π΄Π°ΠΊΡΠΈΡΡ POSIX). ΠΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΊΠΎΠ½ΡΡΡΡΠΊΡΠΈΠΈ Π²ΠΈΠ΄Π°:
if (sem_open( ... ) == -1)
ΠΏΡΠΎΡΡΠΎ Π²ΡΠ·ΠΎΠ²Π΅Ρ ΡΠΈΠ½ΡΠ°ΠΊΡΠΈΡΠ΅ΡΠΊΡΡ ΠΎΡΠΈΠ±ΠΊΡ (Π½Π΅ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΠΈΠ΅ ΡΠΈΠΏΠΎΠ²) ΠΈ Π½Π΅ ΠΏΡΠΎΠΉΠ΄Π΅Ρ ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡΠΈΡ! ΠΡΡΠ΅ΡΡΠ²Π΅Π½Π½Π΅Π΅ Π±ΡΠ»ΠΎ Π±Ρ Π΄Π»Ρ ΡΠ°ΠΊΠΎΠΉ ΡΡΠ½ΠΊΡΠΈΠΈ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°ΡΡ NULL Π² ΡΠ»ΡΡΠ°Π΅ ΠΎΡΠΈΠ±ΠΊΠΈ, Π½ΠΎ... ΡΠ°ΠΊ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΎ Π² POSIX. ΠΡΠΎΠΌΠ΅ ΡΠΎΠ³ΠΎ, Π²ΠΎ ΠΌΠ½ΠΎΠ³ΠΈΡ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΡΡ UNIX ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ΅ΡΡΡ ΠΊΠΎΠ½ΡΡΠ°Π½ΡΠ°:
#define SEM_FAILED ((sem_t*)(-1))
Π Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΠ°ΡΠΈΠΈ QNX ΠΎΠ½Π° Π½ΠΈΠ³Π΄Π΅ Π½Π΅ ΡΠΏΠΎΠΌΠΈΠ½Π°Π΅ΡΡΡ, Π½ΠΎ, ΠΊΠ°ΠΊ ΠΌΡ Π²ΠΈΠ΄ΠΈΠΌ, ΠΎΠ½Π° ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Π°, ΠΈ Π²ΡΠ΅ ΠΏΡΠ΅ΠΊΡΠ°ΡΠ½ΠΎ ΡΠ°Π±ΠΎΡΠ°Π΅Ρ!
2. Π€ΡΠ½ΠΊΡΠΈΡ ΠΏΠΎΡΠΎΠΊΠ° ΠΏΡΠΈΠ½ΠΈΠΌΠ°Π΅Ρ Π²ΠΈΠ΄ (ΡΠ΅ΠΏΠ΅ΡΡ sem, Π² ΠΎΡΠ»ΠΈΡΠΈΠ΅ ΠΎΡ ΠΏΡΠ΅Π΄ΡΠ΅ΡΡΠ²ΡΡΡΠ΅Π³ΠΎ ΡΠ»ΡΡΠ°Ρ, Π²Π΅Π΄Ρ ΡΠ΅ΠΏΠ΅ΡΡ ΡΡΠΎ ΡΠΆΠ΅ ΡΠΊΠ°Π·Π°ΡΠ΅Π»Ρ Π½Π° ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΡ ΡΠΈΠΏΠ° sem_t):
void* threadfunc(void* data) {
...
while (i++ != N) {
t1 = ClockCycles();
sem_wait(sem);
if (debug) str[ind++] = *tid;
sem_post(sem);
t += ClockCycles() - t1;
sched_yield();
}
...
}
3. Π’Π΅ΠΏΠ΅ΡΡ ΠΎΡΠΎΠ±ΠΎΠ΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ ΡΠ΄Π΅Π»ΠΈΡΡ Π½Π΅ ΡΠΎΠ»ΡΠΊΠΎ ΡΠΎΠ·Π΄Π°Π½ΠΈΡ, Π½ΠΎ ΠΈ Π»ΠΈΠΊΠ²ΠΈΠ΄Π°ΡΠΈΠΈ ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½Π½ΠΎΠ³ΠΎ ΡΠ΅ΠΌΠ°ΡΠΎΡΠ° (ΡΠ°ΠΊΠΎΠΉ ΡΠ΅ΠΌΠ°ΡΠΎΡ ΠΈΠΌΠ΅Π΅Ρ Π²ΡΠ΅ΠΌΡ ΠΆΠΈΠ·Π½ΠΈ ΡΠ΄ΡΠ° ΡΠΈΡΡΠ΅ΠΌΡ ΠΈ Π±ΡΠ΄Π΅Ρ ΠΏΡΠΎΠ΄ΠΎΠ»ΠΆΠ°ΡΡ ΡΠ²ΠΎΠ΅ ΡΡΡΠ΅ΡΡΠ²ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΈ ΠΏΠΎΡΠ»Π΅ Π·Π°Π²Π΅ΡΡΠ΅Π½ΠΈΡ Π½Π°ΡΠ΅Π³ΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ):
sem_close(sem);
sem_unlink(semname);
ΠΠ°ΠΏΡΡΡΠΈΠΌ ΠΏΠΎΠ»ΡΡΠ΅Π½Π½ΠΎΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΏΡΠΈ ΡΠ°ΠΊΠΎΠΌ Π·Π½Π°ΡΠ΅Π½ΠΈΠΈ -n, ΠΊΠΎΡΠΎΡΠΎΠ΅ ΠΎΠ±Π΅ΡΠΏΠ΅ΡΠΈΡ Π΄ΠΎΡΡΠ°ΡΠΎΡΠ½ΠΎΠ΅ Π²ΡΠ΅ΠΌΡ Π΅Π³ΠΎ ΡΠ°Π±ΠΎΡΡ. ΠΡΠ΅ΠΆΠ΄Π΅ ΡΠ΅ΠΌ ΠΎΠ±ΡΡΠΆΠ΄Π°ΡΡ ΠΏΠΎΠ»ΡΡΠ΅Π½Π½ΡΠ΅ ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΡ, ΠΏΠΎΡΠΌΠΎΡΡΠΈΠΌ ΠΎΡΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠ΅ ΡΠ΅ΠΌΠ°ΡΠΎΡΠ° Π½Π° ΠΏΡΠΎΡΡΡΠ°Π½ΡΡΠ²ΠΎ ΡΠ°ΠΉΠ»ΠΎΠ²ΡΡ ΠΈΠΌΠ΅Π½ ΡΠΈΡΡΠ΅ΠΌΡ Π²ΠΎ Π²ΡΠ΅ΠΌΡ ΡΠ°Π±ΠΎΡΡ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ:
# ls -l /dev/sem
total 1
n------r-Ρ 1 root root 1 Feb 10 18.56 duble
Π ΡΠ΅ΠΏΠ΅ΡΡ ΠΈ ΡΠ΅Π·ΡΠ»ΡΡΠ°ΡΡ ΡΠ°Π±ΠΎΡΡ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ:
# nice -n-19 sy20n -n100000
3 : cycles - 1453746002, on semaphore - 14537
2 : cycles - 1454203573, on semaphore - 14542
ΠΠ°ΠΊΠΎΠ½Π΅Ρ, ΠΌΡ ΠΌΠΎΠΆΠ΅ΠΌ ΠΎΠ±ΡΠ°ΡΠΈΡΡΡΡ ΠΊ ΠΊΠΎΠ»ΠΈΡΠ΅ΡΡΠ²Π΅Π½Π½ΠΎΠΌΡ Π°Π½Π°Π»ΠΈΠ·Ρ ΠΏΠΎΠ»ΡΡΠ΅Π½Π½ΡΡ ΡΠΈΡΡ:
β’ ΠΡΠΈΠΌΠΈΡΠΈΠ²Ρ β ΠΌΡΡΡΠ΅ΠΊΡ, Π½Π΅ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½Π½ΡΠΉ ΠΈ ΠΈΠΌΠ΅Π½ΠΎΠ²Π°Π½Π½ΡΠΉ ΡΠ΅ΠΌΠ°ΡΠΎΡΡ, β ΠΊΠ°ΠΆΡΡΠΈΠ΅ΡΡ Π½Π° ΠΏΠ΅ΡΠ²ΡΠΉ Π²Π·Π³Π»ΡΠ΄ ΡΡ ΠΎΠ΄Π½ΡΠΌΠΈ, ΡΡΠ΅Π±ΡΡΡ Π΄Π»Ρ ΡΠ²ΠΎΠ΅Π³ΠΎ ΠΎΠ±ΡΠ»ΡΠΆΠΈΠ²Π°Π½ΠΈΡ Π² ΡΠΊΠ²ΠΈΠ²Π°Π»Π΅Π½ΡΠ½ΡΡ ΡΡΠ»ΠΎΠ²ΠΈΡΡ ΠΏΡΠΈΠ½ΡΠΈΠΏΠΈΠ°Π»ΡΠ½ΠΎ ΡΠ°Π·Π»ΠΈΡΠ½ΡΡ Π·Π°ΡΡΠ°Ρ, Π²Π΅Π»ΠΈΡΠΈΠ½Ρ ΠΊΠΎΡΠΎΡΡΡ ΡΠ°Π΄ΠΈΠΊΠ°Π»ΡΠ½ΠΎ ΠΎΡΠ»ΠΈΡΠ°ΡΡΡΡ: 140 β 870 β 14500 ΠΏΡΠΎΡΠ΅ΡΡΠΎΡΠ½ΡΡ ΡΠΈΠΊΠ»ΠΎΠ² ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²Π΅Π½Π½ΠΎ, ΡΡΠΎ ΡΠΎΠΎΡΠ½ΠΎΡΠΈΡΡΡ ΠΊΠ°ΠΊ 1:6,2:104.
β’ Π’Π°ΠΊ ΠΆΠ΅ ΡΠ°Π΄ΠΈΠΊΠ°Π»ΡΠ½ΠΎ ΠΎΡΠ»ΠΈΡΠ°ΡΡΡΡ ΠΈ ΠΈΡ Ρ Π°ΡΠ°ΠΊΡΠ΅ΡΠΈΡΡΠΈΠΊΠΈ Π΄ΠΎΡΡΡΠΏΠ°: ΠΈΠ·Π½ΡΡΡΠΈ ΠΏΡΠΎΡΠ΅ΡΡΠ° (ΠΈΠ»ΠΈ Π΄Π°ΠΆΠ΅ ΡΠΎΠ»ΡΠΊΠΎ ΠΈΠ· ΡΠΎΠ³ΠΎ ΠΏΠΎΡΠΎΠΊΠ°, ΠΊΠΎΡΠΎΡΡΠΉ ΡΠΆΠ΅ Π²Π»Π°Π΄Π΅Π΅Ρ ΠΌΡΡΡΠ΅ΠΊΡΠΎΠΌ), ΠΈΠ· Π²Π½Π΅ΡΠ½Π΅Π³ΠΎ ΠΏΡΠΎΡΠ΅ΡΡΠ°, ΠΈΠ· ΠΏΡΠΎΡΠ΅ΡΡΠ°, ΡΠ°Π±ΠΎΡΠ°ΡΡΠ΅Π³ΠΎ Π½Π° ΡΠΎΠ²Π΅ΡΡΠ΅Π½Π½ΠΎ Π΄ΡΡΠ³ΠΎΠΌ ΡΠ΅ΡΠ΅Π²ΠΎΠΌ ΡΠ·Π»Π΅β¦ Π’ΠΎ, ΡΡΠΎ ΠΌΡ ΡΠΆΠ΅ ΡΠ°ΡΡΠΌΠ°ΡΡΠΈΠ²Π°Π»ΠΈ ΠΊΠ°ΠΊ Β«Ρ Π°ΡΠ°ΠΊΡΠ΅ΡΠΈΡΡΠΈΠΊΠΈ Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ ΠΆΠΈΠ·Π½ΠΈΒ» ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠ², ΠΏΡΠΈΠ½Π°Π΄Π»Π΅ΠΆΠΈΡ ΡΠ°Π·Π»ΠΈΡΠ½ΡΠΌ ΠΊΠ°ΡΠ΅Π³ΠΎΡΠΈΡΠΌ: ΠΏΡΠΎΡΠ΅ΡΡΠ° (process-persistent), ΡΠ΄ΡΠ° (kernel-persistent) ΠΈΠ»ΠΈ ΡΠ°ΠΉΠ»ΠΎΠ²ΠΎΠΉ ΡΠΈΡΡΠ΅ΠΌΡ (filesystem-persistent).