使用pthreads,如何在C中初始化静态的互斥量数组?
对于单个静态互斥锁,似乎我可以使用PTHREAD_MUTEX_INITIALIZER.但是它们的静态数组呢?例如,在
#include <pthread.h> #define NUM_THREADS 5 /*initialize static mutex array*/ static pthread_mutex_t mutexes[NUM_THREADS] = ...?
或者必须动态分配?
以下代码在执行时打印nitesh null而不是预期nitesh 130.为什么n在执行静态块之前没有初始化?
class test
{
static
{
System.out.println(test.str+" "+test.n);
}
final static String str="nitesh";
final static Float n=130f;
public static void main(String []args)
{
}
}
Run Code Online (Sandbox Code Playgroud) 注意:这是不是重复,请仔细阅读题目сarefully /sf/users/241389361/报价:
真正的问题是为什么代码有时会起作用.即使没有lambdas,问题也会重现.这让我觉得可能存在JVM错误.
在/sf/answers/3759645221/的评论中,我试图找出原因,为什么代码的行为从一个开始到另一个不同,并且该讨论的参与者给了我一些建议来创建一个单独的主题.
不要考虑以下源代码:
public class Test {
static {
System.out.println("static initializer: " + Thread.currentThread().getName());
final long SUM = IntStream.range(0, 5)
.parallel()
.mapToObj(i -> {
System.out.println("map: " + Thread.currentThread().getName() + " " + i);
return i;
})
.sum();
}
public static void main(String[] args) {
System.out.println("Finished");
}
}
Run Code Online (Sandbox Code Playgroud)
有时(几乎总是)它会导致死锁.
输出示例:
static initializer: main
map: main 2
map: ForkJoinPool.commonPool-worker-3 4
map: ForkJoinPool.commonPool-worker-3 3
map: ForkJoinPool.commonPool-worker-2 0
Run Code Online (Sandbox Code Playgroud)
但有时它会成功完成(非常罕见):
static initializer: main
map: main 2
map: main …Run Code Online (Sandbox Code Playgroud) 例:
struct Foo { Foo() { printf("foo\n"); } };
static Foo foo;
__attribute__((constructor)) static void _bar() { printf("bar\n"); }
Run Code Online (Sandbox Code Playgroud)
它是确定性的foo还是bar首先印刷的?
(我希望并且期望静态对象的构造函数总是先执行但不确定,并且GCC关于构造函数属性的文档没有说明任何内容.)
public class Main {
public static void main(String[] args) {
System.out.println(B.x);
}
}
class A {
public static String x = "x";
}
class B extends A {
static {
System.out.print("Inside B.");
}
}
Run Code Online (Sandbox Code Playgroud)
问题:为什么输出将是:x.但不是:Inside B.x
请考虑以下示例:
tt.h声明了一个带有外部链接的全局常量 extern int g_TRAGIC;
tt.cpp定义g_TRAGIC如下 const int g_TRAGIC = 0xF001;
my.cpp希望用它来定义自己的全局常量 const int g_MAGIC = g_TRAGIC;
当我读到iso-FAQ时,我会认为这会导致静态初始化顺序失败.然而,iso-FAQ注意到
在某些情况下,静态初始化顺序fiasco也可以应用于内置/内部类型.
这是什么某些情况下,是什么意思?对于内置/内在类型,我们在哪些条件下保存并从SIOF发出声音,特别是常量?或者必须将Construct On First Use Idiom用于所有具有外部链接的常量?
注意:在实际代码中,我无法更改g_TRAGIC的定义.
我想看看我是否可以初始化一个全局变量来指向自己:
#include <stdio.h>
struct foo { struct foo *a, *b; } x = { &x, &x };
int main()
{
printf("&x = %p, x.a = %p, x.b = %p\n", &x, x.a, x.b);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
此代码编译并按预期运行gcc(所有三个指针打印相同).
我想知道:
编辑:只是为了澄清,我质疑x其自己的初始化程序中的地址的可用性.
c gcc recursive-datastructures circular-reference static-initialization
给定一个带有初始化方法的静态类:
public static class Foo
{
// Class members...
internal static init()
{
// Do some initialization...
}
}
Run Code Online (Sandbox Code Playgroud)
如何确保之前运行初始化程序Main()?
我能想到的最好的是将其添加到Foo:
private class Initializer
{
private static bool isDone = false;
public Initializer()
{
if (!isDone)
{
init();
isDone = true;
}
}
}
private static readonly Initializer initializer = new Initializer();
Run Code Online (Sandbox Code Playgroud)
这会有用还是有一些不可预见的警告?还有更好的方法吗?
我目前正在研究Go Lang教程,但遇到了其中一个练习的问题:
https://tour.golang.org/methods/23
练习让我实现了一个ROT13密码.我决定使用从字节到旋转值的映射来实现密码,但我不确定初始化此映射的最佳方法.我不想使用文字初始化地图,但更喜欢通过循环遍历字母表并在循环内设置(键,值)对来编程.我还希望只能从Rot13Reader结构/对象访问该地图,并让所有实例(?)共享相同的地图(而不是每个Rot13Reader一个副本).
这是我目前正在进行的Go计划:
package main
import (
"io"
"os"
"strings"
)
type rot13Reader struct {
r io.Reader
}
var rot13Map = map[byte]byte{}
func (rotr *rot13Reader) Read(p []byte) (int, error) {
n, err := rotr.r.Read(p)
for i := 0; i < n; i++ {
if sub := rot13Map[p[i]]; sub != byte(0) {
p[i] = sub
}
}
return n, err
}
func main() {
func() {
var uppers = []byte("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
var lowers = []byte("abcdefghijklmnopqrstuvwxyz")
var init = func (alphabet …Run Code Online (Sandbox Code Playgroud) 假设您需要从函数中知道是否已将此函数作为静态对象初始化的一部分进行调用.是否有标准或特定于平台的方法?
我深入研究了许多应用程序使用的DLL的源代码.这个DLL暴露了一个Init函数,这个函数应该构造一个boost::asio::deadline_timer稍后使用的函数(但是DLL可以在没有降级模式的情况下工作).
问题是在静态对象初始化期间(DLL加载时间)不能构造定时器,以免其构造函数死锁.
当然,每个人和他们的猫Init来自世界各地(是的,多次!),包括来自源代码的静态构造函数我不会编辑,因此需要检测那种情况并挽救.
在实用主义克服了厌恶之后,我最终走上了callstack试图找到wWinMain并推断出静态初始化结束了.这很糟糕,并且不适用于动态加载的二进制文件,幸好这不在我的特定情况范围内.我当然希望有一种更清洁的方式.
c++ ×3
java ×3
c ×2
gcc ×2
static ×2
.net ×1
c# ×1
concurrency ×1
deadlock ×1
go ×1
inheritance ×1
initializer ×1
jvm-hotspot ×1
mutex ×1
pthreads ×1