[英]Why does pthread_create() returns 0 but the thread never starts
我来自Java背景,对使用Java的同步进行多线程编程感到很满意。 最近,我开始涉足C ++,不得不处理一些多线程代码。 以下是我面临的问题的最小可行示例。
class TxStatus {
private:
int numOperations;
bool commitStatus;
pthread_mutex_t statusLock;
public:
TxStatus() {
this->commitStatus = false;
this->numOperations = 0;
}
void addNewOperation() {
pthread_mutex_lock(&statusLock);
numOperations++;
pthread_mutex_unlock(&statusLock);
}
void operationCompleted() {
pthread_mutex_lock(&statusLock);
numOperations--;
pthread_mutex_unlock(&statusLock);
}
void commit() {
this->commitStatus = true;
}
};
class TxManager {
private:
unsigned long long globalFrontier;
unsigned long long txId;
pthread_mutex_t gfLock;
pthread_mutex_t txIdLock;
std::map<unsigned long long, TxStatus> txStatusMap;
public:
TxManager() {
pthread_mutex_lock(&gfLock);
globalFrontier = 1;
pthread_mutex_unlock(&gfLock);
pthread_mutex_lock(&txIdLock);
txId = 1;
pthread_mutex_unlock(&txIdLock);
}
unsigned long long beginNewTx() {
pthread_mutex_lock(&txIdLock);
unsigned long long newId = txId;
txId++;
pthread_mutex_unlock(&txIdLock);
TxStatus statusObj;
txStatusMap.insert(std::make_pair(newId,statusObj));
return newId;
}
void addUnflushedOperation(unsigned long long txId) {
txStatusMap[txId].addNewOperation();
}
void markOperationAsFlushed(unsigned long long txId) {
txStatusMap[txId].operationCompleted();
}
void markCommitted(unsigned long long txId) {
txStatusMap[txId].commit();
}
};
void * thread( void *args){
TxManager txManager;
fprintf(stderr,"Inside thread");
unsigned long long newTxId = txManager.beginNewTx();
fprintf(stderr,"Tx Started: %d", newTxId );
txManager.addUnflushedOperation(newTxId);
pthread_exit(NULL);
}
int main(){
pthread_t tx_thread;
fprintf(stderr,"Inside main");
int ret = pthread_create(&tx_thread, NULL, thread, NULL);
if (ret != 0)
{
fprintf(stderr,"Error launching thread");
}else{
fprintf(stderr,"Thread launched successfully");
}
if (pthread_join(tx_thread, NULL) != 0)
{
fprintf(stderr,"Join pthread failed");
}
return 0;
}
线程成功启动,但是我从线程本身执行的函数(即thread())中看不到任何打印结果。 如果我删除了join调用,那么程序将在main方法中打印语句后终止。
两件事情:
您似乎在构造函数中缺少对pthread_mutex_init的调用。 那可能是问题的一部分。
另一个问题是您的fprintf语句需要换行。
也就是说,这一行:
fprintf(stderr,"Inside thread");
更新为:
fprintf(stderr,"Inside thread\n");
\\n
char将刷新输出缓冲区,以便您的消息实际出现在屏幕上。
对其他打印语句进行类似处理。
同样,您似乎对每个变量使用了不同的锁。 考虑只具有一个互斥体实例。 而且您可能也不需要锁定TxStatus。
Pthreads是一个C库。 它的数据类型是哑C类型。 如果仅将它们放在类或结构中,它们将不会自动初始化。 您需要初始化它们。 最简单的方法是使用PTHREAD_MUTEX_INITIALIZER
(或者使用pthread_mutex_init
),在C ++中,您可以在成员声明旁边进行操作。
这不会挂起:
#include <pthread.h>
#include <map>
#include <stdio.h>
using namespace std;
class TxStatus {
private:
int numOperations;
bool commitStatus;
pthread_mutex_t statusLock = PTHREAD_MUTEX_INITIALIZER;
public:
TxStatus() {
this->commitStatus = false;
this->numOperations = 0;
}
void addNewOperation() {
pthread_mutex_lock(&statusLock);
numOperations++;
pthread_mutex_unlock(&statusLock);
}
void operationCompleted() {
pthread_mutex_lock(&statusLock);
numOperations--;
pthread_mutex_unlock(&statusLock);
}
void commit() {
this->commitStatus = true;
}
};
class TxManager {
private:
unsigned long long globalFrontier;
unsigned long long txId;
pthread_mutex_t gfLock = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t txIdLock = PTHREAD_MUTEX_INITIALIZER;
std::map<unsigned long long, TxStatus> txStatusMap;
public:
TxManager() {
pthread_mutex_lock(&gfLock);
globalFrontier = 1;
pthread_mutex_unlock(&gfLock);
pthread_mutex_lock(&txIdLock);
txId = 1;
pthread_mutex_unlock(&txIdLock);
}
unsigned long long beginNewTx() {
pthread_mutex_lock(&txIdLock);
unsigned long long newId = txId;
txId++;
pthread_mutex_unlock(&txIdLock);
TxStatus statusObj;
txStatusMap.insert(std::make_pair(newId,statusObj));
return newId;
}
void addUnflushedOperation(unsigned long long txId) {
txStatusMap[txId].addNewOperation();
}
void markOperationAsFlushed(unsigned long long txId) {
txStatusMap[txId].operationCompleted();
}
void markCommitted(unsigned long long txId) {
txStatusMap[txId].commit();
}
};
void * thread( void *args){
TxManager txManager;
fprintf(stderr,"Inside thread\n");
unsigned long long newTxId = txManager.beginNewTx();
fprintf(stderr,"Tx Started: %llu", newTxId );
txManager.addUnflushedOperation(newTxId);
pthread_exit(NULL);
}
int main(){
pthread_t tx_thread;
fprintf(stderr,"Inside main\n");
int ret = pthread_create(&tx_thread, NULL, thread, NULL);
if (ret != 0)
{
fprintf(stderr,"Error launching thread");
}else{
fprintf(stderr,"Thread launched successfully");
}
if (pthread_join(tx_thread, NULL) != 0)
{
fprintf(stderr,"Join pthread failed");
}
return 0;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.