- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
实际上,我之前在 Correct way to shutdown C application to ensure CRITICAL sections completed? 上问过类似的问题,但想重新开始,问是否任何人都可以看到以下代码的基本问题。
我基本上提出了一个概念证明,它是这样的:
注意:从线程到主应用程序的回调是必不可少的,我想知道这是否是“糟糕的编程实践”....
代码正在根据输出运行,这里是一个示例:
lynton@lynton ~/Desktop/ThreadTest $ ./main
Main program started
In thread testMainLoop
Transaction started in spawned thread
onBeginTransaction in main thread
onMessageArrived in main thread
onCommitTransaction in main thread
Transaction ended in spawned thread
Transaction started in spawned thread
onBeginTransaction in main thread
onMessageArrived in main thread
onCommitTransaction in main thread
Transaction ended in spawned thread
Transaction started in spawned thread
onBeginTransaction in main thread
onMessageArrived in main thread
onCommitTransaction in main thread
Transaction ended in spawned thread
^CIn shutdown hook...
Thread still running
listenForMessages loop completed in spawned thread
In onProcessingComplete in main thread
Exciting testMainLoop
All thread transactions complete
Main program exiting
lynton@lynton ~/Desktop/ThreadTest $
在上面你可以看到关闭钩子(Hook)被启动并且应用程序优雅地结束......
基础测试代码如下:
请特别注意“(*onProcessingCompleteCallbackFunc)(TRUE);”从线程调用主应用程序,告诉主应用程序该线程已 100% 完成。 pthread_join 似乎无法正常工作,因为我需要它在这里......
注意:以下是我创建的主应用程序使用的共享库 (libwmq_sender.so)。
wmq_sender.h
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define TRUE 0
#define FALSE 1
int wmq_sender_start();
int wmq_sender_stop();
void wmq_sender_registerOnBeginTransactionCallback(int (*callbackFunc)(char *tid));
void wmq_sender_registerOnCommitTransactionCallback(int (*callbackFunc)(char *tid));
void wmq_sender_registerOnMessageArrivedCallback(int (*callbackFunc)(char *tid, char *buffer, int size));
void wmq_sender_registerOnProcessingCompleteCallback(void (*callbackFunc)(int completeFlag));
int listenForMessages();
int (*onBeginTransactionCallbackFunc)(char *tid);
int (*onCommitTransactionCallbackFunc)(char *tid);
int (*onRollbackTransactionCallbackFunc)(char *tid);
int (*onMessageArrivedCallbackFunc)(char *tid, char *buffer, int size);
void (*onProcessingCompleteCallbackFunc)(int completeFlag);
int running;
int rc;
int transactionRunning;
wmq_sender.c
#include "wmq_sender.h"
int listenForMessages(){
char *uuid = NULL;;
char *buffer = NULL;
uuid = malloc(10 * sizeof(char));
strcpy(uuid, "1234567891");
buffer = malloc(11 * sizeof(char));
strcpy(buffer, "test_buffer");
while(running == TRUE){
printf("Transaction started in spawned thread\n");
transactionRunning = TRUE;
(*onBeginTransactionCallbackFunc)(uuid);
(*onMessageArrivedCallbackFunc)(uuid, buffer, 11);
(*onCommitTransactionCallbackFunc)(uuid);
transactionRunning = FALSE;
printf("Transaction ended in spawned thread\n");
sleep(2);
}
printf("listenForMessages loop completed in spawned thread\n");
free(uuid);
free(buffer);
(*onProcessingCompleteCallbackFunc)(TRUE);
return 0;
}
int wmq_sender_start(){
return listenForMessages();
}
int wmq_sender_stop(){
running = FALSE;
return 0;
}
void wmq_sender_registerOnBeginTransactionCallback(int (*callbackFunc)(char *tid)){
onBeginTransactionCallbackFunc = callbackFunc;
}
void wmq_sender_registerOnCommitTransactionCallback(int (*callbackFunc)(char *tid)){
onCommitTransactionCallbackFunc = callbackFunc;
}
void wmq_sender_registerOnMessageArrivedCallback(int (*callbackFunc)(char *tid, char *buffer, int size)){
onMessageArrivedCallbackFunc = callbackFunc;
}
void wmq_sender_registerOnProcessingCompleteCallback(void (*callbackFunc)(int completeFlag)){
onProcessingCompleteCallbackFunc = callbackFunc;
}
以下是生成线程并正常关闭等的主应用程序。
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <pthread.h>
#include <time.h>
#include "wmq_sender.h"
#define TRUE 0
#define FALSE 1
void *testMainLoop(void *arg);
void shutdownHook(int sig);
int main(int argc, char * argv[]);
int onBeginTransaction(char *tid);
int onCommitTransaction(char *tid);
int onMessageArrived(char *tid, char *buffer, int size);
void onProcessingComplete(int completeFlag);
pthread_t testThread;
int threadRunning;
int rc;
void *testMainLoop(void *arg){
printf("In thread testMainLoop\n");
wmq_sender_registerOnBeginTransactionCallback(onBeginTransaction);
wmq_sender_registerOnCommitTransactionCallback(onCommitTransaction);
wmq_sender_registerOnMessageArrivedCallback(onMessageArrived);
wmq_sender_registerOnProcessingCompleteCallback(onProcessingComplete);
threadRunning = TRUE;
rc = wmq_sender_start();
printf("Exciting testMainLoop\n");
}
void shutdownHook(int sig){
printf("In shutdown hook...\n");
rc = wmq_sender_stop();
while(threadRunning == TRUE){
printf("Thread still running\n");
sleep(2);
}
printf("All thread transactions complete\n");
}
void onProcessingComplete(int completeFlag){
printf("In onProcessingComplete in main thread\n");
threadRunning = FALSE;
}
int main(int argc, char * argv[]){
(void) signal(SIGINT, shutdownHook);
printf("Main program started\n");
rc = pthread_create(&testThread, NULL, testMainLoop, (void *)argv);
pthread_join(testThread, NULL);
printf("Main program exiting\n");
return 0;
}
int onBeginTransaction(char *tid){
printf("onBeginTransaction in main thread\n");
return 0;
}
int onCommitTransaction(char *tid){
printf("onCommitTransaction in main thread\n");
return 0;
}
int onMessageArrived(char *tid, char *buffer, int size){
printf("onMessageArrived in main thread\n");
return 0;
}
在我的测试机上编译是:
gcc -m64 -Wall -g -I./ -c ./main.c -o ./main.o
gcc -m64 -o ./main ./main.o -L./ -L/usr/lib -L/usr/local/lib -lpthread -lwmq_sender
gcc -m64 -Wall -g -c -I./ -I/usr/local/include/ -fPIC ./wmq_sender.c -o ./wmq_sender.o
gcc -shared -o ./libwmq_sender.so ./wmq_sender.o
export LD_LIBRARY_PATH="/home/lynton/Desktop/ThreadTest"
您认为我使用 CALLBACKS 告诉主应用程序线程已完成等的方式有什么问题吗?
任何帮助或建议将不胜感激;-)
谢谢
林顿
最佳答案
您确实意识到您的回调函数实际上是在线程上运行的,不是吗?据我所见,您的主线程只是创建另一个线程来完成所有操作,然后等待它完成。我认为目前创建第二个线程没有任何意义。
无论如何,您遇到的另一个可怕的问题是您的信号处理程序调用 printf
和 sleep
。我非常确定在信号处理程序中调用 printf 并不安全,sleep 也不安全。实际上它应该做的就是设置一个标志来表示“终止”,然后返回。
根据 C99 标准,您无法可靠地分配给任何未声明为 volatile sig_atomic_t
的静态变量,也无法调用除 abort()
之外的任何标准库函数、_Exit()
或 signal()
以及最后一个与您收到的信号编号相同的信号。
关于c - 确保事务在 SHUTDOWN Hook 上全部完成...示例代码检查,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7965696/
我正在使用 PostgREST 将数据库实体暴露给使用这些实体的 Springboot 应用。 我的数据库中有两个实体,分别是 Person 和 City。 我想同时保存 Person 实体和 Cit
1、事务的定义 Redis的事务提供了一种“将多个命令打包, 然后一次性、按顺序地执行”的机制。 redis事务的主要作用就是串联多个命令防止别的命令插队。 但是,事务并不具有传统
SQLite 事务(Transaction) 事务(Transaction)是一个对数据库执行工作单元。事务(Transaction)是以逻辑顺序完成的工作单位或序列,可以是由用户手动操作完成,也可
事务是顺序组操作。 它们作为单个单元运行,并且直到组中的所有操作都成功执行时才终止。 组中的单个故障会导致整个事务失败,并导致对数据库没有影响。 事务符合ACID(原子性,一致性,隔离和耐久性)
我希望将 SqlKata 用于一个项目。但是,项目标准的一部分是查询应该能够作为事务执行。有没有一种方法可以使用 MSSQL 事务执行一个查询或多个查询? 非常感谢。 最佳答案 SQLKata 使用
我只是以多线程方式测试 PetaPoco 事务... 我有一个简单的测试用例: -- 简单的值对象称之为 MediaDevice -- 插入一条记录,更新1000次 void TransactionT
我正在尝试从 Excel VBA 向 SQL 中插入一些数据。 SQL 命令是在 VBA 脚本的过程中构建的,包括使用一些 SQL 变量。 我试图了解事务在 VBA 中是如何工作的,以及它们是否可以处
情况如下: 一个大型生产客户端/服务器系统,其中一个中央数据库表具有某个列,该列的默认值是 NULL,但现在默认值是 0。但是在该更改之前创建的所有行当然仍然具有 null 值,这会在该系统中生成许多
数据库事务是一个熟悉的概念。 try { ... .. updateDB() .. ... commit(); } catch error { rollback(); }
我想了解使用传播支持进行 Spring 交易的用途。 java 文档提到如果具有 @Transactional(propagation = Propagation.SUPPORTS) 的方法从支持该事
我需要获取 hibernate 的事务 ID。对于每笔交易,此 ID 必须是唯一的。我尝试使用 session.getTransaction().hashCode(),但我相信这个值不是唯一的。 最佳
我从 firebase 收到以下消息:runTransactionBlock:启用持久性时检测到的使用情况。请注意,事务不会在应用重新启动后保留。 那么应用程序重新启动后到底会发生什么?由于主数据库的
我需要在 jdbc 中执行选择、更新、插入查询的序列。 这是我的代码: public String editRequest(){ connection = DatabaseUtil.getServi
Java 是否提供了一种智能“聚合”事务的方法?如果我有多个异构数据存储库,我想保持同步(即用于数据的 Postgres、用于图表的 Neo4j 以及用于索引的 Lucene),是否有一个范例仅允许
我对标题中的主题有几个问题。首先,假设我们使用 JDBC,并且有 2 个事务 T1 和 T2。在 T1 中,我们在一个特定的行上执行 select 语句。然后我们对该行执行更新。在事务 T2 中,我们
我有一个 Python CGI 处理支付交易。当用户提交表单时,CGI 被调用。提交后,CGI 需要一段时间才能执行信用卡交易。在此期间,用户可能会按下 ESC 或刷新按钮。这样做不会“杀死”CGI,
我有一个代码,类似这样 def many_objects_saving(list_of_objects): for some_object in list_of_objects:
我有一个包含 100,000 条记录的表。我正在考虑使用事务来更新数据。将有一个查询将一列更新为零,并且大约有 5000 个更新,每个更新将更新一条记录。 这些大型事务对内存有何影响?事务运行时选择数
有没有办法在一个命令中执行 SQL 事务?例如 mysql_query(" START TRANSACTION; INSERT INTO table1 ....etc; INSERT INTO tab
真心希望能帮到你! 我使用以下函数在 PHP/MySql 应用程序中发送消息: public function sendMail($sender_id, $recipient_id, $subject
我是一名优秀的程序员,十分优秀!