线程同步的问题,不知道大家有没有这样用过。

时间:2022-07-10 20:28:52
线程的问题,不知道大家有没有这样用过?写了好几年程序了还真没有好好使用过线程,所以今天和大家探讨一下。

问题:
    主程序A,调用线程B。线程B里面要调用 主程序A里面窗体C,窗体D,窗体E的几个方法,请问大家如何保证我在线程B调用主程序A中的窗体C的方法c1,窗体D的方法d2是安全的。 
使用Synchronize( TThreadMethod &Method); 不停的换函数指针可以不。

举例来说,我要调用C->C1()
我在我的线程里面定义方法CALLC1(),在CALLC1()方法里面调用C->C1()。在开始调用前先调用Synchronize(CALLC1); 来达到方法同步的目的不知道可行不。

12 个解决方案

#1


我认为最好利用锁来解决这个问题,Synchronize并不能保证安全的的。

#2


或者我干脆把C->C1的函数指针传递给Synchronize,Synchronize(C->C1); 来达到方法同步的目的不知道可行不。

我知道用锁是最好的,但是C->C1不是我们写的,我们不能轻易更改别人写的代码。 在不更改C->C1的前提下有没有好的方法。

ps:我是给人家做维护开发,所以能不修改别人写的代码我就尽量不修改。

#3


可以!

#4


关键是所有调c->c1()的地方都要Synchronize方式调用

#5


由于C->C1()方法不是你写的,所以在C1方法内进行保护不现实的。

你可以用一个方法,封装这个C->C1();比如:

void CallC1()
{
    EnterCriticalSection(&m_cs);
    C->C1();
    LeaveCriticalSection(&m_cs);
}

然后将所有的C->C1()调用全部换成CallC1()调用就可以了。

#6


我觉得搂主的方法已经可以了,楼上的方法不能保证其他人也用 m_cs ,因为别人的程序已经写好了。

#7


楼上的,为什么不能保证?

起码调用C->C1()的函数是lz维护的吧,那这样做有什么疑问么?

#8


搂主已经说了,C->C1()函数是别人写的,不能改。

#9


对呀,我没有改C->C1()函数,我改的是调用这个的函数。

C那个类我根本都不动的。你再看看我写的代码吧

#10


我的意思是说,在别人已经写好的程序里,就没有使用

 void CallC1()
{
    EnterCriticalSection(&m_cs);
    C->C1();
    LeaveCriticalSection(&m_cs);
}

而可能会直接调用C->C1();这样上面写的保护是没有用的,因为已经写好的程序里没有同样使用
  
    EnterCriticalSection(&m_cs);
     C->C1();
    LeaveCriticalSection(&m_cs);

而Synchronize(C->C1)不一样,它可以保证C->C1在主线程里运行,从而保证不会发生冲突; 



#11


首先呢,我们讨论的问题建立在lz可以改变C->C1()的调用函数的基础上,就是说,lz可以选择以什么样的方式调用C->C1()函数,但不改变C::C1()本身,不知道你能看懂么~~

按照你所说,既然能将原来的代码改成Synchronize(C->C1),就说明能操作C->C1()的调用方式,所以如果将C->C1()的调用改为用关键代码段包括,是正确的选择。

如果在每个调用C->C1()的函数前面加关键代码段,则很麻烦,所以用一个函数将该操作包装起来,比如说称为:CallC1()这样的。

然后将所有调用C->C1()的地方用CallC1()取代之,这也理所当然。

最后,如果按你所说,Synchronize只能使代码在主线程中运行,那么我的代码要好多了,不管多少个线程同时运行,在C->C1()函数中都是线程安全的。

请以后仔细思考别人的代码后作答,谢谢

#12


赫赫,谢谢两位老大了。

#1


我认为最好利用锁来解决这个问题,Synchronize并不能保证安全的的。

#2


或者我干脆把C->C1的函数指针传递给Synchronize,Synchronize(C->C1); 来达到方法同步的目的不知道可行不。

我知道用锁是最好的,但是C->C1不是我们写的,我们不能轻易更改别人写的代码。 在不更改C->C1的前提下有没有好的方法。

ps:我是给人家做维护开发,所以能不修改别人写的代码我就尽量不修改。

#3


可以!

#4


关键是所有调c->c1()的地方都要Synchronize方式调用

#5


由于C->C1()方法不是你写的,所以在C1方法内进行保护不现实的。

你可以用一个方法,封装这个C->C1();比如:

void CallC1()
{
    EnterCriticalSection(&m_cs);
    C->C1();
    LeaveCriticalSection(&m_cs);
}

然后将所有的C->C1()调用全部换成CallC1()调用就可以了。

#6


我觉得搂主的方法已经可以了,楼上的方法不能保证其他人也用 m_cs ,因为别人的程序已经写好了。

#7


楼上的,为什么不能保证?

起码调用C->C1()的函数是lz维护的吧,那这样做有什么疑问么?

#8


搂主已经说了,C->C1()函数是别人写的,不能改。

#9


对呀,我没有改C->C1()函数,我改的是调用这个的函数。

C那个类我根本都不动的。你再看看我写的代码吧

#10


我的意思是说,在别人已经写好的程序里,就没有使用

 void CallC1()
{
    EnterCriticalSection(&m_cs);
    C->C1();
    LeaveCriticalSection(&m_cs);
}

而可能会直接调用C->C1();这样上面写的保护是没有用的,因为已经写好的程序里没有同样使用
  
    EnterCriticalSection(&m_cs);
     C->C1();
    LeaveCriticalSection(&m_cs);

而Synchronize(C->C1)不一样,它可以保证C->C1在主线程里运行,从而保证不会发生冲突; 



#11


首先呢,我们讨论的问题建立在lz可以改变C->C1()的调用函数的基础上,就是说,lz可以选择以什么样的方式调用C->C1()函数,但不改变C::C1()本身,不知道你能看懂么~~

按照你所说,既然能将原来的代码改成Synchronize(C->C1),就说明能操作C->C1()的调用方式,所以如果将C->C1()的调用改为用关键代码段包括,是正确的选择。

如果在每个调用C->C1()的函数前面加关键代码段,则很麻烦,所以用一个函数将该操作包装起来,比如说称为:CallC1()这样的。

然后将所有调用C->C1()的地方用CallC1()取代之,这也理所当然。

最后,如果按你所说,Synchronize只能使代码在主线程中运行,那么我的代码要好多了,不管多少个线程同时运行,在C->C1()函数中都是线程安全的。

请以后仔细思考别人的代码后作答,谢谢

#12


赫赫,谢谢两位老大了。