C++下让一个函数阻塞,但整个进程不会挂起,这个函数并不在线程里

时间:2021-02-22 14:53:49
如题,有这种功能的函数吗
如果用Sleep()的话,整个进程就会挂起,求解

37 个解决方案

#1


可以考虑wait某些事件
感觉还是得另开线程去等待

#2


sleep 进程怎么会挂起?你说的是ui线程挂起把?

#3


开新线程等待不就行了,

要满足怎样的目的?

#4


SendCmd(char *cmd)
{
    send(cmd);
    while(1)
    {
        //循环查看一个变量,看这个变时是否为true,为true则break。而这个变量是由另一个函数改变
          Sleep(1);

    }

}


就是这样子,这里我用线程相当不好做。我希望在这里边不用Sleep,因为Sleep会导致整个进程挂起。

#5


我查了有个叫
Application.ProcessMessage()
的东西,但是这个要怎么用呢
需要include那个包呢。

#6


"函数不在线程里",这句话该怎么理解呢?

#7


为什么要阻塞

#8


是不是说只要编写一个永远不会被调用的函数,然后在函数里wait,就可以了?

#9


Suspend 那个函数所在线程。

#10


引用 6 楼 yanran_hill 的回复:
"函数不在线程里",这句话该怎么理解呢?

因为如果在一个线程中,sleep 不会让整个进程挂起

#11


主线程也是线程

#12


引用 9 楼 saleayas 的回复:
Suspend 那个函数所在线程。


说了,不是线程中

#13


函数不在线程中??
那叫代码!

#14


看来楼主还不知道什么是线程

#15


感觉楼主想说的是,该进程不是一个多线程进程。另外,楼主所说的阻塞,也不是说execution flow被阻塞了(如果是这个意思,那么应该是不可能的。详情见下),而是说函数从外部看,没在往下执行;如果是这样,那么,据我所知,只有busy waiting这种方法。
以下阐述不可能阻塞execution flow而不挂起进程的原因:一个进程,如果没有被挂起,那么其状态为RUNNING,此时,经过一段时间,它总会被CPU调用(比如,在Linux上,其优先级会随着时间推移逐步上升,所以,一段时间后,一定会被调用),此时,将会执行下一条命令;如果此时的命令流被阻塞了,即,不能执行下一行,那么该进程应该会被挂起,其状态不该为RUNNING。由此推出矛盾。
(PS: 初学,说的不一定对。详细情况建议查看操作系统相关资料。)

#16


引用 13 楼 saleayas 的回复:
函数不在线程中??
那叫代码!

好吧,照你这么说,我要把主线程给挂起么

#17


楼主想要的是ui能够响应输入

#18


你需要把当前线程中正在执行的线程挂起吗?

#19


你需要把当前进程中正在执行的线程挂起吗?

#20


我查了下网站,
发现有个
Application.ProcessMessage()
可以满足我的需求
但是这个必须在窗体程里使用,dll里想要用的话该怎么办呢
有谁可以帮我解决下这个吗

#21


楼主的意思是 在主线程中有个函数 想要这个函数运行到一半挂起 但是主线程不挂起

#22


引用 20 楼 qnetg123 的回复:
我查了下网站,
发现有个
Application.ProcessMessage()
可以满足我的需求
但是这个必须在窗体程里使用,dll里想要用的话该怎么办呢
有谁可以帮我解决下这个吗

你先说不挂起是什么意思

#23


引用 19 楼 saleayas 的回复:
你需要把当前进程中正在执行的线程挂起吗?


并不是,因为当前进程执行时,我要调用一个函数,这个函数里边有个while{}死循环来判等待一个值
而这里边我用了Sleep()。在执行时会使整个进程挂起了,我就是想怎么让这个执行,但不让整个进程挂起。

网上我找了,好像就Application.ProcessMessage()
满足,但是我不知道要怎么在dll里使用这个东西。

#24


创建一个线程来执行这个函数。

#25


举个例子!
比如串口。

设置到串口之后,创建一个线程去读取串口,此时串口阻塞。
但是,不影响主线程响应消息。

如果,串口获取到数据。可以使用消息或者定义事件。

#26


引用 23 楼 qnetg123 的回复:
引用 19 楼 saleayas 的回复:
你需要把当前进程中正在执行的线程挂起吗?


并不是,因为当前进程执行时,我要调用一个函数,这个函数里边有个while{}死循环来判等待一个值
而这里边我用了Sleep()。在执行时会使整个进程挂起了,我就是想怎么让这个执行,但不让整个进程挂起。

网上我找了,好像就Application.ProcessMessage()
满足,但是我……

那你就用异步,不要轮循等 

#27


在单线程中应该不可能吧

#28


如果一个函数里边有个while(1){Sleep(1)}
当这个函数里边没有跳出来的时候,界面不是全部会卡住,其它代码是不会执行吗。
这时我就是不想变成这样子。
但是说是用一个线程来做,在我这边的设计中不行。
所以我才有此一问

#29


你参考下这个吧。
http://my.oschina.net/u/158589/blog/35668
你可以
while(1)
{
sleep(long enough);
something you wanna do when an event arrives
}

另外,你如果想解决实际的问题的话,最好把自己用的什么系统什么开发环境说下。
这帖子都20楼了,你还没说清楚想要干啥。
另外,乱用术语只会使大家误会你的意思。

#30


引用 28 楼 qnetg123 的回复:
如果一个函数里边有个while(1){Sleep(1)}
当这个函数里边没有跳出来的时候,界面不是全部会卡住,其它代码是不会执行吗。
这时我就是不想变成这样子。
但是说是用一个线程来做,在我这边的设计中不行。
所以我才有此一问

用一个waitabletimer和MsgWaitForMultipleObjectsEx

#31


就是单线程模拟并发执行吧


比如一个逻辑是处理用户输入,另外一个逻辑是读文件处理。
主循环类似:

while(1){
 uiProcess->run();
 filePorcess->run();
}


然后uiProcess->run()和fileprocess->run()都必须是可退出重入的方法。

比如ui的话,可以每次处理一个消息,然后返回,多余的消息存队列。
file部分则可以每次处理一小段数据,记录处理到的位置,下次call时继续处理。

对于更复杂的功能用状态机实现:

另外有个简单点的实现方法:

使用2个脚本对象,逻辑写在脚本里面。然后每次执行一句脚本。

脚本可以代替状态机的控制。


这个实际就是一个比较粗糙的操作系统调度。不同的是操作系统按cpu时间片划分,我们只能按函数划分。


#32


在你的while循环里向主线程发送更新消息。

#33


我知道在.net里面楼主说的这个功能叫多线程

#34


该回复于2012-03-07 09:48:18被版主删除

#35


你主程序可以循环在那,另外得监听信号,当收到某个信号时就退出循环。

#36


最终结果是
利用了
在要等待的地方用
do
{
   GetMessage(&msg,0,0,0);
   if(msg.Message == MessID)
      break;
   TranslateMessage(msg);
   DispatchMessage(msg);
} while(1)

而在其它执行的函数中,用PostThreadMessage向消息队列发一个MessID的消息
从而退出等待

#37


引用 31 楼 kevin_qing 的回复:
就是单线程模拟并发执行吧


比如一个逻辑是处理用户输入,另外一个逻辑是读文件处理。
主循环类似:

while(1){
 uiProcess->run();
 filePorcess->run();
}


然后uiProcess->run()和fileprocess->run()都必须是可退出重入的方法。

比如ui的话,可以每次处理一个消息,然后返回,多余的消息存……


今天重新看了下 ,发现这说得精典

#1


可以考虑wait某些事件
感觉还是得另开线程去等待

#2


sleep 进程怎么会挂起?你说的是ui线程挂起把?

#3


开新线程等待不就行了,

要满足怎样的目的?

#4


SendCmd(char *cmd)
{
    send(cmd);
    while(1)
    {
        //循环查看一个变量,看这个变时是否为true,为true则break。而这个变量是由另一个函数改变
          Sleep(1);

    }

}


就是这样子,这里我用线程相当不好做。我希望在这里边不用Sleep,因为Sleep会导致整个进程挂起。

#5


我查了有个叫
Application.ProcessMessage()
的东西,但是这个要怎么用呢
需要include那个包呢。

#6


"函数不在线程里",这句话该怎么理解呢?

#7


为什么要阻塞

#8


是不是说只要编写一个永远不会被调用的函数,然后在函数里wait,就可以了?

#9


Suspend 那个函数所在线程。

#10


引用 6 楼 yanran_hill 的回复:
"函数不在线程里",这句话该怎么理解呢?

因为如果在一个线程中,sleep 不会让整个进程挂起

#11


主线程也是线程

#12


引用 9 楼 saleayas 的回复:
Suspend 那个函数所在线程。


说了,不是线程中

#13


函数不在线程中??
那叫代码!

#14


看来楼主还不知道什么是线程

#15


感觉楼主想说的是,该进程不是一个多线程进程。另外,楼主所说的阻塞,也不是说execution flow被阻塞了(如果是这个意思,那么应该是不可能的。详情见下),而是说函数从外部看,没在往下执行;如果是这样,那么,据我所知,只有busy waiting这种方法。
以下阐述不可能阻塞execution flow而不挂起进程的原因:一个进程,如果没有被挂起,那么其状态为RUNNING,此时,经过一段时间,它总会被CPU调用(比如,在Linux上,其优先级会随着时间推移逐步上升,所以,一段时间后,一定会被调用),此时,将会执行下一条命令;如果此时的命令流被阻塞了,即,不能执行下一行,那么该进程应该会被挂起,其状态不该为RUNNING。由此推出矛盾。
(PS: 初学,说的不一定对。详细情况建议查看操作系统相关资料。)

#16


引用 13 楼 saleayas 的回复:
函数不在线程中??
那叫代码!

好吧,照你这么说,我要把主线程给挂起么

#17


楼主想要的是ui能够响应输入

#18


你需要把当前线程中正在执行的线程挂起吗?

#19


你需要把当前进程中正在执行的线程挂起吗?

#20


我查了下网站,
发现有个
Application.ProcessMessage()
可以满足我的需求
但是这个必须在窗体程里使用,dll里想要用的话该怎么办呢
有谁可以帮我解决下这个吗

#21


楼主的意思是 在主线程中有个函数 想要这个函数运行到一半挂起 但是主线程不挂起

#22


引用 20 楼 qnetg123 的回复:
我查了下网站,
发现有个
Application.ProcessMessage()
可以满足我的需求
但是这个必须在窗体程里使用,dll里想要用的话该怎么办呢
有谁可以帮我解决下这个吗

你先说不挂起是什么意思

#23


引用 19 楼 saleayas 的回复:
你需要把当前进程中正在执行的线程挂起吗?


并不是,因为当前进程执行时,我要调用一个函数,这个函数里边有个while{}死循环来判等待一个值
而这里边我用了Sleep()。在执行时会使整个进程挂起了,我就是想怎么让这个执行,但不让整个进程挂起。

网上我找了,好像就Application.ProcessMessage()
满足,但是我不知道要怎么在dll里使用这个东西。

#24


创建一个线程来执行这个函数。

#25


举个例子!
比如串口。

设置到串口之后,创建一个线程去读取串口,此时串口阻塞。
但是,不影响主线程响应消息。

如果,串口获取到数据。可以使用消息或者定义事件。

#26


引用 23 楼 qnetg123 的回复:
引用 19 楼 saleayas 的回复:
你需要把当前进程中正在执行的线程挂起吗?


并不是,因为当前进程执行时,我要调用一个函数,这个函数里边有个while{}死循环来判等待一个值
而这里边我用了Sleep()。在执行时会使整个进程挂起了,我就是想怎么让这个执行,但不让整个进程挂起。

网上我找了,好像就Application.ProcessMessage()
满足,但是我……

那你就用异步,不要轮循等 

#27


在单线程中应该不可能吧

#28


如果一个函数里边有个while(1){Sleep(1)}
当这个函数里边没有跳出来的时候,界面不是全部会卡住,其它代码是不会执行吗。
这时我就是不想变成这样子。
但是说是用一个线程来做,在我这边的设计中不行。
所以我才有此一问

#29


你参考下这个吧。
http://my.oschina.net/u/158589/blog/35668
你可以
while(1)
{
sleep(long enough);
something you wanna do when an event arrives
}

另外,你如果想解决实际的问题的话,最好把自己用的什么系统什么开发环境说下。
这帖子都20楼了,你还没说清楚想要干啥。
另外,乱用术语只会使大家误会你的意思。

#30


引用 28 楼 qnetg123 的回复:
如果一个函数里边有个while(1){Sleep(1)}
当这个函数里边没有跳出来的时候,界面不是全部会卡住,其它代码是不会执行吗。
这时我就是不想变成这样子。
但是说是用一个线程来做,在我这边的设计中不行。
所以我才有此一问

用一个waitabletimer和MsgWaitForMultipleObjectsEx

#31


就是单线程模拟并发执行吧


比如一个逻辑是处理用户输入,另外一个逻辑是读文件处理。
主循环类似:

while(1){
 uiProcess->run();
 filePorcess->run();
}


然后uiProcess->run()和fileprocess->run()都必须是可退出重入的方法。

比如ui的话,可以每次处理一个消息,然后返回,多余的消息存队列。
file部分则可以每次处理一小段数据,记录处理到的位置,下次call时继续处理。

对于更复杂的功能用状态机实现:

另外有个简单点的实现方法:

使用2个脚本对象,逻辑写在脚本里面。然后每次执行一句脚本。

脚本可以代替状态机的控制。


这个实际就是一个比较粗糙的操作系统调度。不同的是操作系统按cpu时间片划分,我们只能按函数划分。


#32


在你的while循环里向主线程发送更新消息。

#33


我知道在.net里面楼主说的这个功能叫多线程

#34


该回复于2012-03-07 09:48:18被版主删除

#35


你主程序可以循环在那,另外得监听信号,当收到某个信号时就退出循环。

#36


最终结果是
利用了
在要等待的地方用
do
{
   GetMessage(&msg,0,0,0);
   if(msg.Message == MessID)
      break;
   TranslateMessage(msg);
   DispatchMessage(msg);
} while(1)

而在其它执行的函数中,用PostThreadMessage向消息队列发一个MessID的消息
从而退出等待

#37


引用 31 楼 kevin_qing 的回复:
就是单线程模拟并发执行吧


比如一个逻辑是处理用户输入,另外一个逻辑是读文件处理。
主循环类似:

while(1){
 uiProcess->run();
 filePorcess->run();
}


然后uiProcess->run()和fileprocess->run()都必须是可退出重入的方法。

比如ui的话,可以每次处理一个消息,然后返回,多余的消息存……


今天重新看了下 ,发现这说得精典