我正在使用 POSIX 執行緒處理 C 網路應用程式。我遇到了一個問題,即用作監視器的子執行緒未檢測到主執行緒對全域計數器所做的更改(增量)。我設法將相關代碼提取到以下3個檔案中并重現了問題。
// common.h
#ifndef COMMON_H
#define COMMON_H
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <errno.h>
#include <pthread.h>
#include <sys/resource.h>
static volatile int glob = 0;
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
void increment_clients_count();
#endif
// common.c
#include "common.h"
void increment_clients_count()
{
// Lock
pthread_mutex_lock(&mutex);
glob ;
// Unlock
pthread_mutex_unlock(&mutex);
}
// thread_incr_wrong.c
// main function
#include "common.h"
void /* Loop 'arg' times incrementing 'glob' */
monitor()
{
while(1)
{
time_t current_time;
time(¤t_time);
char *t = ctime(¤t_time);
if (t[strlen(t)-1] == '\n') t[strlen(t)-1] = '\0';
printf("%s, Count : %d\n", t, glob);
sleep(3);
}
}
int
main(int argc, char *argv[])
{
pthread_t t1;
int s;
s = pthread_create(&t1, NULL, (void*)monitor, NULL);
if (s != 0){
perror("pthread_create");
exit(1);
}
while(1){
increment_clients_count();
sleep(5);
}
exit(0);
}
當這條鱈魚跑的時候,我希望看到
Tue Jan 11 18:56:24 2022, Count : 1
Tue Jan 11 18:56:27 2022, Count : 1
Tue Jan 11 18:56:30 2022, Count : 2
Tue Jan 11 18:56:33 2022, Count : 2
Tue Jan 11 18:56:36 2022, Count : 3
Tue Jan 11 18:56:39 2022, Count : 4
Tue Jan 11 18:56:42 2022, Count : 4
Tue Jan 11 18:56:45 2022, Count : 5
Tue Jan 11 18:56:48 2022, Count : 5
Tue Jan 11 18:56:51 2022, Count : 6
Tue Jan 11 18:56:54 2022, Count : 7
相反,輸出看起來像這樣
Tue Jan 11 18:59:40 2022, Count : 0
Tue Jan 11 18:59:43 2022, Count : 0
Tue Jan 11 18:59:46 2022, Count : 0
Tue Jan 11 18:59:49 2022, Count : 0
Tue Jan 11 18:59:52 2022, Count : 0
監控執行緒沒有看到glob變數每 5 秒遞增一次。
請讓我知道我在代碼中哪里做錯了。
如果您想嘗試重現該問題,您可以復制這 3 個檔案并 cc -std=c99 -D_XOPEN_SOURCE=600 -D_DEFAULT_SOURCE -g -pedantic -Wall -W -Wmissing-prototypes -Wno-sign-compare -Wimplicit-fallthrough -Wno-unused-parameter -pthread -o thread_incr_wrong thread_incr_wrong.c common.c在任何 Linux 機器上構建可執行檔案
。可執行檔案的名稱是thread_incr_wrong。
謝謝
uj5u.com熱心網友回復:
兩者glob和mutex都被宣告為static。這意味著當 common.h 包含在 common.c 和 main.c 中時,它們每個都有自己的這些變數的副本。
全域變數應該在一個頭檔案中宣告,所有源檔案都可以看到它們并在一個源檔案中定義。因此,將標頭中的內容更改為外部宣告并將定義放在 common.c 中:
常見的.h:
extern volatile int glob;
extern pthread_mutex_t mutex;
常見的.c:
volatile int glob = 0;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/409605.html
標籤:
