2.Β Π€ΡΠ½ΠΊΡΠΈΡ ΠΏΠΎΡΠΎΠΊΠ° ΠΏΡΠΈΠ½ΠΈΠΌΠ°Π΅Ρ Π²ΠΈΠ΄ (ΡΠ΅ΠΏΠ΅ΡΡ
semsem_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).
β’Β Π£ Π·Π°Ρ Π²Π°ΡΠ΅Π½Π½ΠΎΠ³ΠΎ ΠΌΡΡΡΠ΅ΠΊΡΠ° Π²ΡΠ΅Π³Π΄Π° Π΅ΡΡΡ ΠΏΠΎΡΠΎΠΊ-Π²Π»Π°Π΄Π΅Π»Π΅Ρ, ΠΈ ΡΠΎΠ»ΡΠΊΠΎ ΠΎΠ½ ΠΌΠΎΠΆΠ΅Ρ ΠΎΡΠ²ΠΎΠ±ΠΎΠ΄ΠΈΡΡ Π΅Π³ΠΎ Π² Π΄Π°Π»ΡΠ½Π΅ΠΉΡΠ΅ΠΌ. ΠΠΌΠ΅Π½Π½ΠΎ ΠΏΠΎΡΡΠΎΠΌΡ ΠΌΡΡΡΠ΅ΠΊΡ ΠΌΠΎΠΆΠ΅Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡΡΡ Π΄Π»Ρ ΡΠΈΠ½Ρ ΡΠΎΠ½ΠΈΠ·Π°ΡΠΈΠΈ ΠΏΠΎΡΠΎΠΊΠΎΠ², Π½ΠΎ ΡΠΎΠ»ΡΠΊΠΎ ΡΠΈΠ½Ρ ΡΠΎΠ½ΠΈΠ·Π°ΡΠΈΠΈ Π² ΡΠΌΡΡΠ»Π΅ ΡΠ°Π·Π³ΡΠ°Π½ΠΈΡΠ΅Π½ΠΈΡ Π²ΡΠ΅ΠΌΠ΅Π½Π½ΠΎΠΉ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΠ΅Π»ΡΠ½ΠΎΡΡΠΈ Π΄ΠΎΡΡΡΠΏΠ°ΠΊ ΡΡΠ°Π³ΠΌΠ΅Π½ΡΡ ΠΊΠΎΠ΄Π° β ΠΊ ΡΠΎΠΌΡ, ΡΡΠΎ ΡΠ°ΡΡΠΎ Π½Π°Π·ΡΠ²Π°ΡΡ ΠΊΡΠΈΡΠΈΡΠ΅ΡΠΊΠΎΠΉ ΡΠ΅ΠΊΡΠΈΠ΅ΠΉ ΠΊΠΎΠ΄Π°. Π€ΡΠ½ΠΊΡΠΈΠΎΠ½Π°Π»ΡΠ½ΠΎΡΡΡ ΡΠ΅ΠΌΠ°ΡΠΎΡΠ° Π·Π½Π°ΡΠΈΡΠ΅Π»ΡΠ½ΠΎ Π²ΡΡΠ΅: ΠΏΡΠΈ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΠΈ (ΠΏΠΎΡΡΠΈ Π²ΡΠ΅Π³Π΄Π°) Π΅Π³ΠΎ ΠΏΡΠΈΠΌΠ΅Π½Π΅Π½ΠΈΡ Π² ΡΠΎΠΌ ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡΠ΅, Π² ΠΊΠΎΡΠΎΡΠΎΠΌ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ ΠΈ ΠΌΡΡΡΠ΅ΠΊΡ (ΡΠΎΠ»ΡΠΊΠΎ Π½ΡΠΆΠ½ΠΎ Π»ΠΈ ΡΡΠΎ Π΄Π΅Π»Π°ΡΡ?), ΠΎΠ½ ΠΌΠΎΠΆΠ΅Ρ ΠΏΡΠΈΠΌΠ΅Π½ΡΡΡΡΡ ΠΈ Π΄Π»Ρ ΡΠΈΠ½Ρ ΡΠΎΠ½ΠΈΠ·Π°ΡΠΈΠΈ ΠΏΠΎΡΠΎΠΊΠΎΠ² Π² ΡΠΌΡΡΠ»Π΅ ΠΊΠΎΠΎΡΠ΄ΠΈΠ½Π°ΡΠΈΠΈ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΠ΅Π»ΡΠ½ΠΎΡΡΠΈΠΈΡ Π²Π·Π°ΠΈΠΌΠΎΠ΄Π΅ΠΉΡΡΠ²ΠΈΡ Π² ΠΊΠ°ΡΠ΅ΡΡΠ²Π΅ ΡΠ»Π΅ΠΌΠ΅Π½ΡΠ°, ΡΠΏΡΠ°Π²Π»ΡΡΡΠ΅Π³ΠΎ ΠΏΠΎΡΡΠ΄ΠΊΠΎΠΌ Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ. ΠΠΎΠΊΠ°ΠΆΠ΅ΠΌ ΡΡΠΎ Π½Π° ΠΏΡΠΈΠΌΠ΅ΡΠ΅. ΠΠ»Ρ ΡΡΠΎΠ³ΠΎ Π½Π΅Π·Π½Π°ΡΠΈΡΠ΅Π»ΡΠ½ΠΎ ΡΡΠ°Π½ΡΡΠΎΡΠΌΠΈΡΡΠ΅ΠΌ ΠΊΠΎΠ΄ ΠΏΡΠ΅Π΄ΡΠ΄ΡΡΠ΅Π³ΠΎ ΡΠ΅ΡΡΠ° Π΄Π»Ρ ΡΠ΅ΠΌΠ°ΡΠΎΡΠ° ( ΡΠ°ΠΉΠ» sy21.cc):
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include <iostream.h>
#include <unistd.h>
#include <pthread.h>
#include <errno.h>
#include <semaphore.h>
unsigned long N = 1000;
unsigned int T = 2;
static sem_t* sem;
static bool debug = false;
static char* str; // ΡΡΡΠΎΠΊΠ° Π΄ΠΈΠ°Π³Π½ΠΎΡΡΠΈΠΊΠΈ
static volatile int ind = 0;
uint64_t *t;
void* threadfunc(void* data) {
Β unsigned long i = 0;
Β char tid[8];
Β sprintf(tid, "%X", pthread_self());
Β // Π²ΡΠ΅ΠΌΠ΅Π½Π½Π°Ρ ΠΌΠ΅ΡΠΊΠ° Π½Π°ΡΠ°Π»Π° Π²ΠΎ Π²ΡΠ΅Ρ
ΠΏΠΎΡΠΎΠΊΠ°Ρ
ΡΡΡΠ°Π½Π°Π²Π»ΠΈΠ²Π°Π΅ΡΡΡ
Β // Π½Π° Π²ΡΠ΅ΠΌΡ Π΄ΠΎΡΡΠΈΠΆΠ΅Π½ΠΈΡ ΡΡΠΎΠΉ ΡΠΎΡΠΊΠΈ Π² ΠΏΠΎΡΠ»Π΅Π΄Π½Π΅ΠΌ (Π°ΠΊΡΠΈΠ²Π½ΠΎΠΌ) ΠΏΠΎΡΠΎΠΊΠ΅
Β if ((int)data == T - 1) {
Β uint64_t Ρ = ClockCycles();
Β for (int i = 0; i < T; i++ ) t[i] = c;
Β }
Β // ΡΠ°Π±ΠΎΡΠΈΠΉ ΡΠΈΠΊΠ» ΠΏΠ΅ΡΠ΅ΠΊΠ»ΡΡΠ΅Π½ΠΈΠΉ Π·Π° ΡΡΠ΅Ρ ΡΠΈΠ½Ρ
ΡΠΎΠ½ΠΈΠ·Π°ΡΠΈΠΈ
Β while (i++ < N) {
Β sem_wait(sem + (int)data);
Β if (debug) str[ind++] = *tid;
Β sem_post(sem + ((int)data +1) % T);
Β }
Β t[(int)data] = ClockCycles() - t[(int)data];
Β return NULL;
}
int main(int argc, char *argv[]) {
Β int opt, val;
Β while ((opt = getopt(argc, argv, "n:t: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 't':
Β Β if (sscanf(optarg, "%i", &val) != 1)
Β Β Β cout << "parse command line error" << endl, exit(EXIT_FAILURE);
Β Β if (val > 0) T = val;
Β Β break;