不同线程间全局变量访问异常

阿门-m 2016-06-06 09:56:53
linux下程序生成可执行文件,A线程能访问B 线程的全局变量,程序正常运行;将本程序打包成库文件后,给另一个程序调用,A线程访问B线程全局变量出现地址值发生改变异常。请教大家,这是什么问题呀?本人有些菜,希望得到大家的指点,谢谢!!!
...全文
331 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
阿门-m 2016-06-12
  • 打赏
  • 举报
回复
引用 16 楼 r_Jimy 的回复:
[quote=引用 12 楼 mgsjon 的回复:] 在另外一个程序调用我的接口,是先初始化后再生成A线程的,这个我能确定。刚又检查一遍,发现调用时使用了两个端口(nport)初始化了两处,同一个全局变量就有两个地址,在后面的程序中使用的是后面的那个地址,这是最初的问题:全局变量地址改变。但是这个后面生成的地址指针里面的内容依然读取不到(为空)。
这里初始化2次是什么情况,同一个变量有两个地址??你的程序是多进程的? [/quote] 程序是多进程的,同一个变量被初始化了两处,但是这两次的地址不一样,同时对应的线程也被初始化了两次,
常书 2016-06-12
  • 打赏
  • 举报
回复
进程间共享数据用共享内存或管道吧
图灵转世 2016-06-08
  • 打赏
  • 举报
回复
对PIC 没有太多的研究。
常书 2016-06-08
  • 打赏
  • 举报
回复
你的PIC可能没加对,估计要看下Makefile.am与Makefile.in之类的文件 你用下这个命令看下 readelf -d xxxx.so|grep TEXTREL 如果上述命令有输出,则不是PIC的,否则就是。PIC的动态链接库不会含有任何代码段重定位表,TEXTREL即代码段重定位表。
常书 2016-06-08
  • 打赏
  • 举报
回复
引用 12 楼 mgsjon 的回复:
在另外一个程序调用我的接口,是先初始化后再生成A线程的,这个我能确定。刚又检查一遍,发现调用时使用了两个端口(nport)初始化了两处,同一个全局变量就有两个地址,在后面的程序中使用的是后面的那个地址,这是最初的问题:全局变量地址改变。但是这个后面生成的地址指针里面的内容依然读取不到(为空)。
这里初始化2次是什么情况,同一个变量有两个地址??你的程序是多进程的?
阿门-m 2016-06-08
  • 打赏
  • 举报
回复
引用 14 楼 r_Jimy 的回复:
[quote=引用 13 楼 mgsjon 的回复:] 大家有没有遇到过在linux下,一全局变量在A线程下可以正常使用,但在B线程中能正确取到地址,里面内容却为空。希望大神能指点下,感激不尽!!!
你的B线程放到A线程中去创建,还会有这个问题吗?[/quote] B线程就是在A线程中创建的,
阿门-m 2016-06-07
  • 打赏
  • 举报
回复
在另外一个程序调用我的接口,是先初始化后再生成A线程的,这个我能确定。刚又检查一遍,发现调用时使用了两个端口(nport)初始化了两处,同一个全局变量就有两个地址,在后面的程序中使用的是后面的那个地址,这是最初的问题:全局变量地址改变。但是这个后面生成的地址指针里面的内容依然读取不到(为空)。
猪头三小队长 2016-06-07
  • 打赏
  • 举报
回复
是如何保证线程B初始化好之后才再生成线程A?你如果是打包成库,那就是提供了供调用的接口,你在本来程序中所使用的策略就不见得有效了。
阿门-m 2016-06-07
  • 打赏
  • 举报
回复
首先,线程B先初始化所有的全局变量后,才再生成A线程,且A线程是个定时器时钟线程,不停的循环读取B线程的全局变量进行操作;这样的逻辑在整个程序生成可执行文件时是没错的,程序是正常的。当整个程序生成库文件给另外一个程序调用时,就出现了B线程中全局变量地址改变的异常,且初始化顺序也是对的,这便是它诡异的地方!@猪头三小队长 @图灵转世
常书 2016-06-07
  • 打赏
  • 举报
回复
引用 13 楼 mgsjon 的回复:
大家有没有遇到过在linux下,一全局变量在A线程下可以正常使用,但在B线程中能正确取到地址,里面内容却为空。希望大神能指点下,感激不尽!!!
你的B线程放到A线程中去创建,还会有这个问题吗?
阿门-m 2016-06-07
  • 打赏
  • 举报
回复
大家有没有遇到过在linux下,一全局变量在A线程下可以正常使用,但在B线程中能正确取到地址,里面内容却为空。希望大神能指点下,感激不尽!!!
图灵转世 2016-06-06
  • 打赏
  • 举报
回复
楼上正解,运行的时候,全局变量可能还没有初始化。
阿门-m 2016-06-06
  • 打赏
  • 举报
回复
由于代码比较多,我就只贴两处关键地方和makefile文件吧这里是定义全局变量及初始化的地方,在主线程里面完成;这里是一个时钟线程,循环读取全局变量地址;srcdir = .
top_srcdir = ..

pkgdatadir = $(datadir)/gtp
pkglibdir = $(libdir)/gtp
pkgincludedir = $(includedir)/gtp
top_builddir = ..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = /usr/bin/install -c
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
bin_PROGRAMS = gtp$(EXEEXT)
subdir = src
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
CONFIG_CLEAN_FILES =
am__installdirs = "$(DESTDIR)$(bindir)"
binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
PROGRAMS = $(bin_PROGRAMS)
am_gtp_OBJECTS = cbcp.$(OBJEXT)\
ccp.$(OBJEXT) chap.$(OBJEXT) ethertypes.$(OBJEXT) file.$(OBJEXT)\
gtpv0Pdp.$(OBJEXT) gre.$(OBJEXT) gtpv0Session.$(OBJEXT) gtpv0SessionMgt.$(OBJEXT)\
gtpv0Tunnel.$(OBJEXT) gtpv1Pdp.$(OBJEXT) gtpv1Session.$(OBJEXT) gtpv1SessionMgt.$(OBJEXT)\
gtpv1Tunnel.$(OBJEXT) gtpv2Pdp.$(OBJEXT) gtpv2Session.$(OBJEXT) gtpv2SessionMgt.$(OBJEXT)\
gtpv2Tunnel.$(OBJEXT) hash.$(OBJEXT) ip.$(OBJEXT) ip_protocols.$(OBJEXT) \
hexbuffer.$(OBJEXT) ipcp.$(OBJEXT) lcp.$(OBJEXT) packet_manip.$(OBJEXT) \
payload.$(OBJEXT) ppp.$(OBJEXT) strmap.$(OBJEXT) \
utilities.$(OBJEXT) ipv4FragPacketPrcs.$(OBJEXT)\
main.$(OBJEXT) packetStream.$(OBJEXT) packetWorker.$(OBJEXT) \
protoPrcs.$(OBJEXT) session.$(OBJEXT) sessionMgt.$(OBJEXT) \
tunnel.$(OBJEXT) dataHandle.$(OBJEXT) cdma_packetWorker.$(OBJEXT) worker.$(OBJEXT)\
shared_mem.$(OBJEXT)
# ./writeshm/mainDeal.$(OBJEXT)
gtp_OBJECTS = $(am_gtp_OBJECTS)
gtp_LDADD = $(LDADD)
DEFAULT_INCLUDES = -I. -I$(srcdir)
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CXX)
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
SOURCES = $(gtp_SOURCES)
DIST_SOURCES = $(gtp_SOURCES)
RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
html-recursive info-recursive install-data-recursive \
install-exec-recursive install-info-recursive \
install-recursive installcheck-recursive installdirs-recursive \
pdf-recursive ps-recursive uninstall-info-recursive \
uninstall-recursive
ETAGS = etags
CTAGS = ctags
DIST_SUBDIRS = $(SUBDIRS)
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = ${SHELL} /home/gtp/missing --run aclocal-1.9
AMDEP_FALSE = #
AMDEP_TRUE =
AMTAR = ${SHELL} /home/gtp/missing --run tar
AUTOCONF = ${SHELL} /home/gtp/missing --run autoconf
AUTOHEADER = ${SHELL} /home/gtp/missing --run autoheader
AUTOMAKE = ${SHELL} /home/gtp/missing --run automake-1.9
AWK = gawk
CC = gcc
CCDEPMODE = depmode=gcc3
CFLAGS = -g #-O2
CPP = gcc -E
CPPFLAGS =
CXX = g++
CXXDEPMODE = depmode=gcc3
CXXFLAGS = -g #-O2
CYGPATH_W = #echo
DEFS = -DPACKAGE_NAME=\"gtp\" -DPACKAGE_TARNAME=\"gtp\" -DPACKAGE_VERSION=\"0.2\" -DPACKAGE_STRING=\"gtp\ 0.2\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE=\"gtp\" -DVERSION=\"0.2\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_ARPA_INET_H=1 -DHAVE_MEMORY_H=1 -DHAVE_NETINET_IN_H=1 -DHAVE_STDINT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_SYS_TIME_H=1 -DHAVE_SYS_TIMEB_H=1 -DHAVE_UNISTD_H=1 -DHAVE__BOOL=1 -DHAVE_STDBOOL_H=1 -DTIME_WITH_SYS_TIME=1 -DHAVE_STDLIB_H=1 -DHAVE_MALLOC=1 -DHAVE_FTIME=1 -DHAVE_GETTIMEOFDAY=1 -DHAVE_MEMSET=1 -DHAVE_MKDIR=1 -D_GNU_SOURCE
DEPDIR = .deps
ECHO_C =
ECHO_N = -n
ECHO_T =
EGREP = grep -E
EXEEXT =
INSTALL_DATA = ${INSTALL} -m 644
INSTALL_PROGRAM = ${INSTALL}
INSTALL_SCRIPT = ${INSTALL}
INSTALL_STRIP_PROGRAM = ${SHELL} $(install_sh) -c -s
LDFLAGS =
LIBOBJS =
LIBS = -lpthread -lpcap -lrt -ldl
LTLIBOBJS =
MAKEINFO = ${SHELL} /home/gtp/missing --run makeinfo
OBJEXT = o
PACKAGE = gtp
PACKAGE_BUGREPORT =
PACKAGE_NAME = gtp
PACKAGE_STRING = gtp 0.2
PACKAGE_TARNAME = gtp
PACKAGE_VERSION = 0.2
PATH_SEPARATOR = :
RANLIB = ranlib
SET_MAKE =
SHELL = /bin/sh
STRIP =
VERSION = 0.2
ac_ct_CC = gcc
ac_ct_CXX = g++
ac_ct_RANLIB = ranlib
ac_ct_STRIP =
am__fastdepCC_FALSE = #
am__fastdepCC_TRUE =
am__fastdepCXX_FALSE = #
am__fastdepCXX_TRUE =
am__include = include
am__leading_dot = .
am__quote =
am__tar = ${AMTAR} chof - "$$tardir"
am__untar = ${AMTAR} xf -
bindir = ${exec_prefix}/bin
build_alias =
datadir = ${prefix}/share
exec_prefix = ${prefix}
host_alias =
includedir = ${prefix}/include
infodir = ${prefix}/info
install_sh = /home/gtp/install-sh
libdir = ${exec_prefix}/lib
libexecdir = ${exec_prefix}/libexec
localstatedir = ${prefix}/var
mandir = ${prefix}/man
mkdir_p = mkdir -p --
oldincludedir = /usr/include
prefix = /usr/local
program_transform_name = s,x,x,
sbindir = ${exec_prefix}/sbin
sharedstatedir = ${prefix}/com
sysconfdir = ${prefix}/etc
target_alias =
SUBDIRS = log hash
gtp_SOURCES = cbcp.h cbcp.cpp ccp.h ccp.cpp chap.h chap.cpp cdma_packetWorker.cpp cdma_packetWorker.h\
ethertypes.h ethertypes.cpp file.cpp file.h gtpv0Pdp.cpp gtpv0Pdp.h gtpv0Session.cpp gtpv0Session.h\
gtpv0SessionMgt.cpp gtpv0SessionMgt.h gtpv0Tunnel.cpp gtpv0Tunnel.h gtpv1Pdp.cpp gtpv1Pdp.h \
gtpv1Session.cpp gtpv1Session.h gtpv1SessionMgt.cpp gtpv1SessionMgt.h gtpv1Tunnel.cpp gtpv1Tunnel.h\
gtpv2Pdp.cpp gtpv2Pdp.h gtpv2Session.cpp gtpv2Session.h gtpv2SessionMgt.cpp gtpv2SessionMgt.h\
gtpv2Tunnel.cpp gtpv2Tunnel.h hexbuffer.cpp hexbuffer.h hash.cpp hash.h\
global.h gre.h gre.c ip.h ip.cpp ip_protocols.h ip_protocols.cpp ip_services.h ip_services.cpp \
lcp.h lcp.cpp local.h packet_manip.h packet_manip.cpp payload.h payload.cpp \
ppp.h ppp.cpp strmap.h strmap.cpp utilities.h \
utilities.cpp ipv4FragPacketPrcs.cpp ipv4FragPacketPrcs.h main.cpp \
packetStream.cpp packetStream.h packetWorker.cpp packetWorker.h \
protoPrcs.cpp protoPrcs.h session.cpp session.h sessionMgt.cpp \
sessionMgt.h tunnel.cpp tunnel.h common.h dataHandle.cpp dataHandle.h\
worker.cpp worker.h shared_mem.cpp shared_mem.H
gtp_LDFLAGS = -D_GNU_SOURCE
all: all-recursive

.SUFFIXES:
.SUFFIXES: .cpp .o .obj
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
&& exit 0; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu src/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;

$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh

$(top_srcdir)/configure: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
install-binPROGRAMS: $(bin_PROGRAMS)
@$(NORMAL_INSTALL)
test -z "$(bindir)" || $(mkdir_p) "$(DESTDIR)$(bindir)"
@list='$(bin_PROGRAMS)'; for p in $$list; do \
p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
if test -f $$p \
; then \
f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
echo " $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \
$(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \
else :; fi; \
done

uninstall-binPROGRAMS:
@$(NORMAL_UNINSTALL)
@list='$(bin_PROGRAMS)'; for p in $$list; do \
f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \
rm -f "$(DESTDIR)$(bindir)/$$f"; \
done

clean-binPROGRAMS:
-test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
gtp$(EXEEXT): $(gtp_OBJECTS) $(gtp_DEPENDENCIES)
# cd ./writeshm/sharedmem && make clean && make
# @rm -f gtp$(EXEEXT)
# $(LINK) $(gtp_LDFLAGS) $(gtp_OBJECTS) $(gtp_LDADD) $(LIBS)
ar rv $@ $^

mostlyclean-compile:
-rm -f *.$(OBJEXT)

distclean-compile:
-rm -f *.tab.c
renwotao2009 2016-06-06
  • 打赏
  • 举报
回复
你贴出你的代码,库加载地址不确定,它影响代码引用的变量的地址,一般要编译成PIC
阿门-m 2016-06-06
  • 打赏
  • 举报
回复
编译成执行文件时都可以访问,但编译成库被其他程序调用后就访问异常了
阿门-m 2016-06-06
  • 打赏
  • 举报
回复
这个全局变量是在B线程(也就是主线程)中定义的,将整个程序编译成库后,这个全局变量,被A线程访问时就异常了,地址值不对了,@renwotao2009
renwotao2009 2016-06-06
  • 打赏
  • 举报
回复
什么叫B线程的全局变量,不应该是库的全局变量吗?所有线程都可以访问的全局变量
猪头三小队长 2016-06-06
  • 打赏
  • 举报
回复
你需要一种机制保证B线程首先初始化好这个全局变量,然后其他线程包括主线程才去访问它,这就需要使用线程间的同步技术,在linux环境下,并不保证哪个线程先运行,哪个线程后运行,一定要自己设计一种同步机制。
阿门-m 2016-06-06
  • 打赏
  • 举报
回复
自己顶一下,着急!
阿门-m 2016-06-06
  • 打赏
  • 举报
回复
是不是要在Makefile文件某处加-fPIC呀?我在CXXFLAGS = -g -fPIC行吗?感觉没有效。

23,116

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧