這是一個跟進this的問題。`pthread_mutex_trylock`和`pthread_mutex_lock`行爲
在該代碼中,當我沒有使用fflush(stdout)
時,輸出沒有被刷新到屏幕上時,我保留了sleep(1)
。
#define S sleep(0)
void* xThread_fn(void* arg)
{
while(1)
{
S;
pthread_mutex_lock(&read_c_mutex);
if(!read_c)
{
pthread_mutex_unlock(&read_c_mutex);
printf(" X");
}
else
{
pthread_mutex_unlock(&read_c_mutex);
pthread_exit(NULL);
}
fflush(stdout); <---THIS ONE HERE
}
}
但是,當我把sleep(0)
沒有必要爲fflush(stdout)
,輸出正常更新stdout
。這是爲什麼?
Q1。爲什麼sleep(0)
的存在會導致輸出刷新的方式發生變化?
如果我修改代碼如下(以跟蹤執行),
#define S sleep(1)
int read_c = 0;
pthread_mutex_t read_c_mutex = PTHREAD_MUTEX_INITIALIZER;
void* inputThread_fn(void* arg)
{
printf("%p is Input\n",pthread_self());
char inputChar;
int i = 0;
while(1)
{
S;
printf("\nChecking input");
scanf("%c",&inputChar);
if(inputChar=='C' || inputChar == 'c')
{
pthread_mutex_trylock(&read_c_mutex);
printf("%p has lock %d\n",pthread_self(),i);
read_c = 1;
pthread_mutex_unlock(&read_c_mutex);
printf("%p has UNlockED %d\n",pthread_self(),i++);
printf("%p is Gone!\n",pthread_self());
fflush(stdout);
pthread_exit(NULL);
}
}
}
void* xThread_fn(void* arg)
{
int i = 0;
printf("%p is X\n",pthread_self());
while(1)
{
S;
printf("X trying for a lock\n");
pthread_mutex_trylock(&read_c_mutex);
printf("%p has lock %d\n",pthread_self(),i);
if(!read_c)
{
pthread_mutex_unlock(&read_c_mutex);
printf("%p has UNlockED %d\n",pthread_self(),i++);
printf("X\n");
fflush(stdout);
}
else
{
printf("%p is Gone!\n",pthread_self());
pthread_mutex_unlock(&read_c_mutex);
fflush(stdout);
pthread_exit(NULL);
}
}
}
void* yThread_fn(void* arg)
{
printf("%p is Y\n",pthread_self());
int i = 0;
while(1)
{
S;
printf("Y trying for a lock\n");
pthread_mutex_trylock(&read_c_mutex);
printf("%p has lock %d\n",pthread_self(),i);
if(!read_c)
{
pthread_mutex_unlock(&read_c_mutex);
printf("%p has UNlockED %d\n",pthread_self(),i++);
printf("Z\n");
fflush(stdout);
}
else
{
printf("%p is Gone!\n",pthread_self());
pthread_mutex_unlock(&read_c_mutex);
fflush(stdout);
pthread_exit(NULL);
}
}
}
一個樣本輸出端是
0xb6700b70 is Input
0xb6f01b70 is Y
0xb7702b70 is X
Checking inputY trying for a lock
0xb6f01b70 has lock 0
0xb6f01b70 has UNlockED 0
Z
X trying for a lock
0xb7702b70 has lock 0
0xb7702b70 has UNlockED 0
X
Y trying for a lock
0xb6f01b70 has lock 1
0xb6f01b70 has UNlockED 1
Z
X trying for a lock
0xb7702b70 has lock 1
0xb7702b70 has UNlockED 1
X
Y trying for a lock
0xb6f01b70 has lock 2
0xb6f01b70 has UNlockED 2
Z
X trying for a lock
0xb7702b70 has lock 2
0xb7702b70 has UNlockED 2
X
Y trying for a lock
0xb6f01b70 has lock 3
0xb6f01b70 has UNlockED 3
Z
X trying for a lock
0xb7702b70 has lock 3
0xb7702b70 has UNlockED 3
X
Y trying for a lock
0xb6f01b70 has lock 4
0xb6f01b70 has UNlockED 4
Z
X trying for a lock
0xb7702b70 has lock 4
0xb7702b70 has UNlockED 4
X
c
Y trying for a lock
0xb6f01b70 has lock 5
0xb6f01b70 has UNlockED 5
Z
X trying for a lock
0xb7702b70 has lock 5
0xb7702b70 has UNlockED 5
X
0xb6700b70 has lock 0
0xb6700b70 has UNlockED 0
0xb6700b70 is Gone!
Y trying for a lock
0xb6f01b70 has lock 6
0xb6f01b70 is Gone!
X trying for a lock
0xb7702b70 has lock 6
0xb7702b70 is Gone!
Q2。我已經使用了pthread_mutex_trylock()
,因爲我希望代碼在while循環中繼續,直到它獲取一個鎖來檢查read_c
的值。 pthread_mutex_lock();
似乎也可以實現。這使我更加困惑。 pthread_mutex_trylock();
太,輸出總是這樣嗎?一個X
後面跟着一個Z
。不會有這樣的情況,它可能會像X
X
Z
X
(假設線程由操作系統切換,ythread嘗試鎖定失敗)?
好的。所以這裏錯了(在'inputThread_fn')? 'pthread_mutex_trylock(&read_c_mutex);' '的printf( 「%p具有鎖定%d \ n」 個,pthread_self()中,i);' 'read_c = 1;' '調用pthread_mutex_unlock(&read_c_mutex);'在這裏,我嘗試鎖如果我沒有得到它,我仍然可以修改數據。所以我需要一個'_lock'而不是'_trylock'。但是,如果我只是讀取數據(如'xthread_fn'和'yThread_fn'),那麼'trylock'就足夠了嗎? – 2013-04-05 12:01:23
簡單的迴應是:除非你真的真的明白它解決了什麼問題,否則不要使用trylock。在大多數情況下,它不是你正在尋找的機器人。實際上,在你的特定情況下,我敢肯定你在一個緩存一致的體系結構中,根本就沒有任何互斥體,任何函數調用都會使編譯器不緩存全局變量的值,因爲讀取並寫入它是原子的(無論如何它只是一個布爾值)。這將打破所有的標準,但可能會奏效。 – Art 2013-04-05 12:06:29
藝術,這是你給同時訪問一個沒有鎖定的全球性壞建議!因此,讓我在最後一句話後面添加「有時」一詞...... – alk 2013-04-05 12:11:52