gpt4 book ai didi

c - pthread_cond_timedwait 在 FreeBSD 中返回 EPERM

转载 作者:行者123 更新时间:2023-11-30 17:07:58 25 4
gpt4 key购买 nike

我有一个可以在其他 Linux 平台上运行的代码库,例如 CentOS、Redhat...但在我的 FreeBSD 10.1 发行版本中失败了。我这里有一个监视器处理程序,它每 10 秒执行一次相同的操作。

前几次正常,返回60(超时),所以monitor_handler继续运行。但是当它返回1(不允许操作)时,处理程序将停止并锁定在pthread_mutex_lock。

我尝试删除 getOSName() 并仅从处理程序中打印一些值,处理程序可以继续运行。但我不确定是否只是时间问题,也许再过几天就会失败。

我也尝试不在 getOSName() 中使用 popen,它可以运行更长时间,但仍然会挂起。但 ret 为 60(超时)并在 pthread_mutex_lock 之后挂起。

有人知道这三种情况吗? FreeBSD 中此功能是否有错误,或者我不能像这样使用它。还有其他方法可以在 FreeBSD 中实现等待和锁定吗?

谢谢。

========更新重现的完整代码====================

    pthread_t monitor_thread;
pthread_mutex_t monitor_lock;
pthread_cond_t monitor_condition;

int start() {
if (getServiceCount() > 0) {
printf("service existed\n");
printErrLog(" ", "service existed");
return EXIT_FAILURE;
}

if (initIni() == EXIT_FAILURE)
exit(EXIT_FAILURE);


struct sigaction act;
//signal terminate call back
memset(&act, '\0', sizeof(act));
act.sa_sigaction = &signal_callback_handler;
act.sa_flags = SA_SIGINFO;
sigaction(SIGTERM, &act, NULL);
skeleton_daemon();
_init_mutex();

mStatus = 1;
getTASInfo();


if (initThread() == EXIT_FAILURE)
exit(EXIT_FAILURE);

return EXIT_SUCCESS;
}

void skeleton_daemon() {
pid_t pid;

pid = fork();

if (pid < 0) {
printf("fork failed!\n");
exit(EXIT_FAILURE);
}
//printf("file name %s\n", pidFile);
if (pid > 0) {
//printf("pid = %d\n", pid);

exit(EXIT_SUCCESS);
}

umask(0);

if (setsid() < 0) {
printf("set sid failed!\n");
exit(EXIT_FAILURE);
}

if (chdir("/") < 0) {
printf("change to root directory failed!\n");
exit(EXIT_FAILURE);
}

int x;

for (x = sysconf(_SC_OPEN_MAX); x > 0; x--) {
close(x);
}

}

int initThread() {
int err;

if (pthread_mutex_init(&monitor_lock, NULL) != 0) {
printf("\n mutex init failed\n");
printErrLog("initThread ", "monitor mutex init failed");
return(EXIT_FAILURE);
}

if (pthread_cond_init(&monitor_condition, NULL) != 0) {
printf("\n condition init failed\n");
printErrLog("initThread ", "monitor condition init failed");
return(EXIT_FAILURE);
}

err = pthread_create(&monitor_thread, NULL, (void *)&monitor_handler, NULL);

if (err != 0) {
printErrLog("pthread_create ", " monitor thread create failed");
return(EXIT_FAILURE);
}

closelog();
pthread_join(monitor_thread, NULL);
return(EXIT_SUCCESS);
}

int initIni() {
config_init(&cfg);
/* Read the file. If there is an error, report it and exit. */
if (!config_read_file(&cfg, ini_file)) {
root = config_root_setting(&cfg);

/* Add some settings to the configuration. */
group = config_setting_add(root, PATH_SEC, CONFIG_TYPE_GROUP);
setting = config_setting_add(group, INSTALLED_PATH_KEY, CONFIG_TYPE_STRING);
config_setting_set_string(setting, installed_path);
setting = config_setting_add(group, LOG_PATH_KEY, CONFIG_TYPE_STRING);
config_setting_set_string(setting, log_file);
setting = config_setting_add(group, ERR_LOG_PATH_KEY, CONFIG_TYPE_STRING);
config_setting_set_string(setting, err_log_file);
setting = config_setting_add(group, COMMAND_LOG_PATH_KEY, CONFIG_TYPE_STRING);
config_setting_set_string(setting, command_log_file);


group = config_setting_add(root, CONFIG_SEC, CONFIG_TYPE_GROUP);
setting = config_setting_add(group, UPDATE_FREQ_KEY, CONFIG_TYPE_INT);
config_setting_set_int(setting, DEFAULT_FREQ);
/* Write out the new configuration. */
if (!config_write_file(&cfg, ini_file))
{
fprintf(stderr, "Error while writing file.\n");
printErrLog("initIni ", "Error while writing file");
config_destroy(&cfg);
return(EXIT_FAILURE);
}

}
else {
config_setting_t *s = config_lookup(&cfg, CONFIG_SEC);
config_setting_lookup_int(s, UPDATE_FREQ_KEY, &updateSec);
}

if (updateSec < MIN_FREQ)
updateSec = MIN_FREQ;
else if (updateSec > MAX_FREQ)
updateSec = MAX_FREQ;
config_destroy(&cfg);
return(EXIT_SUCCESS);
}

void printLog(BYTE * title, BYTE * value) {
FILE *fp = NULL;
fp = fopen(log_file, "a+");
fprintf(fp, "%s %s\n", title, value);
fflush(fp);
fclose(fp);
}

void printIntLog(BYTE * title, int value) {
FILE *fp = NULL;
fp = fopen(log_file, "a+");
fprintf(fp, "%s %d\n", title, value);
fflush(fp);
fclose(fp);
}

void getStartTime() {
FILE *fp = NULL;
fp = fopen(time_file, "r");
memset(mTimeStamp, '\0', sizeof(mTimeStamp));
fgets(mTimeStamp, 5, fp);
fclose(fp);
}

int getTASInfo() {
BYTE *information = NULL;
BYTE *information2 = NULL;

asprintf(&information, "%s%s%s%s%s%s%d%s%s%s", VERSION, ";", BUILD, ";", PROTOCOL_VERSION, ";",
mStatus, ";", mTimeStamp, ";");
asprintf(&information2, "%s%s%s%s%s%s%d%s%x%x%x%x%s", VERSION, ";", BUILD, ";", PROTOCOL_VERSION, ";",
mStatus, ";", mTimeStamp[0], mTimeStamp[1], mTimeStamp[2], mTimeStamp[3],";");
printLog("TAS info ->", information2);

return 0;
}


int getOSName() {
FILE *fp = NULL;
BYTE buffer[BUFFER_SIZE];
BYTE *tmp = NULL;

TRY {
if ((fp = popen("uname", "r")) == NULL) {
THROW (CMD_NOT_FND);
}
else {
if (fgets(buffer, sizeof(buffer), fp) == NULL)
THROW (CMD_NOT_FND);
}
}
CATCH (CMD_NOT_FND) {
buffer[0] = 'n';
buffer[1] = '/';
buffer[2] = 'a';
buffer[3] = '\0';
printErrLog("OS name ->", "command not found");
}
FINALLY {
pclose(fp);
//printf("OS name length %d\n", strlen(buffer));
}
ETRY;

tmp = strrchr(buffer, '\n');

if (tmp)
*tmp = ';';
printf("OS name : %s\n", buffer);
printLog("OS name ->", buffer);

return 0;
}

void signal_callback_handler(int signum, siginfo_t *siginfo, void *context) {

if (signum == SIGTERM) {
clearData();
}
exit(signum);
}

void monitor_handler(void *arg) {
static_flag = 1;
struct timespec outtime;
struct timeval now;
int ret = 0;

pthread_mutex_lock(&monitor_lock);
while (!getStopFlag()) {

getOSName();
gettimeofday(&now, NULL);
outtime.tv_sec = now.tv_sec + updateSec;
outtime.tv_nsec = now.tv_usec * 1000;
ret = pthread_cond_timedwait(&monitor_condition, &monitor_lock, &outtime);
}
pthread_mutex_unlock(&monitor_lock);
pthread_exit(0);
}

最佳答案

我找到了解决办法

for (x = sysconf(_SC_OPEN_MAX); x > 0; x--) {
close(x);
}

上面的代码是系统出错的地方,在FreeBSD下不能使用。您需要将其写入如下

/* close all descriptors */
for (i = getdtablesize(); i >= 0; --i)
{
close(i);
}

/* Route I/O connections */

/* Open STDIN */
i = open("/dev/null", O_RDWR);

/* STDOUT */
dup(i);

/* STDERR */
dup(i);

关于c - pthread_cond_timedwait 在 FreeBSD 中返回 EPERM,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33931856/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com