我尝试在C语言和Manjaro OS上测试多线程。 我写了一个小代码,但遇到一个奇怪的问题
我执行以下简单代码,但未得到预期结果:
#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <semaphore.h>
#define THREADS 4
void *routine1(void * x)
{
int result =2;
pthread_exit((void *)result);
}
int main ()
{
int sum=0;
int retval=0;
pthread_t threads[THREADS];
for ( int i=0;i<THREADS;i++)
pthread_create(&threads[i], NULL, routine1, (void *)i );
for (int i=0; i<THREADS; i++)
{
pthread_join(threads[i],&retval);
sum+=retval;
}
printf("%d\n",sum);
return 0;
}
以上代码的结果是:
2
但我希望在输出中看到8值。调试了几个小时后,我发现如果我在pthread_create()函数之后声明sum变量,则代码将正常运行:
#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <semaphore.h>
#define THREADS 4
void *routine1(void * x)
{
int result =2;
pthread_exit((void *)result);
}
int main ()
{
int retval=0;
pthread_t threads[THREADS];
for ( int i=0;i<THREADS;i++)
pthread_create(&threads[i], NULL, routine1, (void *)i );
int sum=0;
for (int i=0; i<THREADS; i++)
{
pthread_join(threads[i],&retval);
sum+=retval;
}
printf("%d\n",sum);
return 0;
}
代码输出为:
8
这是正确的答案。
我想知道为什么第一个代码是错误的?是因为有pthread_create()函数?
注意:如果您运行此代码,则不关心警告,它们都与强制转换有关
答案 0 :(得分:4)
不,不是不是订单。这是//Here I save my custom peripheral (left and right)
import Foundation
import CoreBluetooth
extension CBPeripheral{
struct Holder {
static var insoleService: CBService!
static var temperatureEnableCharacteristic: CBCharacteristic?
static var batteryLevelCharacteristic: CBCharacteristic?
static var isConnected: Bool = false
static var isThermalEnabled: Bool = false
static var batteryLevel: Int = 0
static var userTemperature: Double = 0
static var topTemperature: Double = 0
static var midTemperature: Double = 0
static var bottomTemperature: Double = 0
static var steps: Int = 0
}
var insoleService: CBService {
get {
return Holder.insoleService
}
set(newValue) {
Holder.insoleService = newValue
}
}
var temperatureEnableCharacteristic: CBCharacteristic {
get {
return Holder.temperatureEnableCharacteristic!
}
set(newValue) {
Holder.temperatureEnableCharacteristic = newValue
}
}
}
的类型。将retval
传递到&retval
时,类型/大小错误。
当pthread_join
是retval
时,它只有4个字节,但是[假设64位编译],int
期望有指向pthread_join
的8个字节的指针。
这将导致未定义的行为,因为该调用会将8个字节写入仅4个字节的变量中。其余4个字节超出了void *
的大小,并可能覆盖堆栈中的任何内容。
在第二个示例中,存在相同的未定义行为,但是我们只是“幸运”并得到了预期的结果(可能是因为堆栈帧中变量的顺序发生了变化,以避免UB产生意外的结果)。但是,两个人仍然拥有UB。
此外,在投射到指针或从指针投射时,我们应该使用retval
而不是long
[以防止编译器警告]。
这是更正的代码:
int