为什么代码在线程之间突变共享变量显然不会受到竞争条件的影响?(Why does code mutating a shared variable across threads apparently NOT suffer from a race condition?)
我正在使用Cygwin GCC并运行此代码:
#include <iostream> #include <thread> #include <vector> using namespace std; unsigned u = 0; void foo() { u++; } int main() { vector<thread> threads; for(int i = 0; i < 1000; i++) { threads.push_back (thread (foo)); } for (auto& t : threads) t.join(); cout << u << endl; return 0; }
用行编译:
g++ -Wall -fexceptions -g -std=c++14 -c main.cpp -o main.o
它打印1000,这是正确的。 但是,由于线程覆盖了先前递增的值,我预计会导致较少的数字。 为什么这个代码不会相互访问?
我的测试机有4个核心,我没有限制我所知道的程序。
当用更复杂的东西替换共享
foo
的内容时,问题仍然存在,例如if (u % 3 == 0) { u += 4; } else { u -= 1; }
I'm using Cygwin GCC and run this code:
#include <iostream> #include <thread> #include <vector> using namespace std; unsigned u = 0; void foo() { u++; } int main() { vector<thread> threads; for(int i = 0; i < 1000; i++) { threads.push_back (thread (foo)); } for (auto& t : threads) t.join(); cout << u << endl; return 0; }
Compiled with the line:
g++ -Wall -fexceptions -g -std=c++14 -c main.cpp -o main.o
.It prints 1000, which is correct. However, I expected a lesser number due to threads overwriting a previously incremented value. Why does this code not suffer from mutual access?
My test machine has 4 cores, and I put no restrictions on the program that I know of.
The problem persists when replacing the content of the shared
foo
with something more complex, e.g.if (u % 3 == 0) { u += 4; } else { u -= 1; }
原文:https://stackoverflow.com/questions/41816495
最满意答案
默认的
HttpClient.Timeout
值为100秒(00:01:40)。 如果你在catch
块中做一个时间戳记,你会注意到这个任务在那个时候开始被取消了。 显然,您每秒可以执行的HTTP请求数量有限,其他人则排队等候。 排队的请求在超时时被取消。 在所有600k的任务中,我个人成功只有2500人,其他人被取消了。我也发现不太可能,你将能够运行整个60万个任务。 许多网络驱动程序只允许很长时间的大量请求,并在一段时间后将该数量减少到非常低的值。 我的网卡允许我在36秒内只发送921个请求,并将该速度降低到每秒只有一个请求。 以这个速度,完成所有的任务将需要一个星期。
如果您能够绕过此限制,请确保为64位平台构建代码,因为该应用程序非常渴望内存。
The default
HttpClient.Timeout
value is 100 seconds (00:01:40). If you do a timestamp in yourcatch
block you will notice that tasks begin to get canceled at exactly that time. Apparently there is a limited number of HTTP requests you can do per second, others get queued. Queued requests get canceled on timeout. Out of all 600k of tasks I personally got only 2500 successful, others got canceled.I also find it unlikely, that you will be able to run the whole 600000 of tasks. Many network drivers let through high number of requests only for a small time, and reduce that number to a very low value after some time. My network card allowed me to send only 921 requests within 36 seconds and dropped that speed to only one request per second. At that speed it will take a week to complete all the tasks.
If you are able to bypass that limitation, make sure you build the code for 64-bit platform as the app is very hungry for memory.
相关问答
更多-
处理取消的IAP交易(Handle cancelled IAP transactions)[2023-08-19]
我们有一个相当可观的用户群,通过移动连接购买东西,只显示提醒 code != SKErrorPaymentCancelled && code != SKErrorPaymentNotAllowed 显然,这是你能做的最好的。 我也看到了你提到的取消上的奇怪行为,据我所知,这是一个框架错误。 We have a pretty substantial user base buying stuff over mobile connections and only show alerts for code != ... -
有两个可能的原因是TaskCanceledException将被抛出: 在任务完成之前,与取消令牌相关联的CancellationTokenSource上的Cancel() CancellationTokenSource 。 请求超时,即在您在HttpClient.Timeout指定的时间段内未完成。 我的猜测是这是一个超时。 (如果是明确的取消,你可能会想到这一点)。通过检查异常可以更加确定: try { var response = task.Result; } catch (TaskCance ...
-
超时的默认值为100秒。 您可以使用Timeout属性将HTTPClient上的超时时间提高到3分钟(或更高)。 httpClient.Timeout = new TimeSpan(0,3,0); The default value for the timeout is 100 seconds. You can up the timeout on the HTTPClient to 3 minutes(or higher) using the Timeout property. httpClient. ...
-
HttpClient - 任务已取消 - 如何获取确切的错误消息?(HttpClient - task was cancelled - How to get the exact error message?)[2023-08-03]
默认的HttpClient.Timeout值为100秒(00:01:40)。 如果你在catch块中做一个时间戳记,你会注意到这个任务在那个时候开始被取消了。 显然,您每秒可以执行的HTTP请求数量有限,其他人则排队等候。 排队的请求在超时时被取消。 在所有600k的任务中,我个人成功只有2500人,其他人被取消了。 我也发现不太可能,你将能够运行整个60万个任务。 许多网络驱动程序只允许很长时间的大量请求,并在一段时间后将该数量减少到非常低的值。 我的网卡允许我在36秒内只发送921个请求,并将该速度降低 ... -
感谢Ankit Vijay的回应,答案必须与您提及的时间一致,我的解决方案就是下一个 我正在使用jsreport embbedserver,并且像这样设置了时间 embeddedReportingServer.ReportingService.HttpClientTimeout = TimeSpan.FromMinutes(40); 用这行代码我停止接收这个错误: TaskCanceledException:任务在呈现jsreport时被取消 然后当我再次测试时,我用phanton过程得到了这个错误: 无 ...
-
您的第一个任务实际上并未被取消 - 您正在观察已经请求取消,但是您正在让第一个任务正常完成...这意味着您的“仅取消”任务被取消。 如果您将代码更改为: while (token.IsCancellationRequested == false) { Console.Write("*"); Thread.Sleep(1000); } token.ThrowIfCancellationRequested(); ......然后它会按照你的预期行事。 Your first task isn't ...
-
有不同的方法来模拟这个。 您可以使用中断边界消息接收事件,如果收到额外信息,则边界事件将取消用户任务。 另一种方法是使用中断事件子过程。 如果收到带有额外信息的消息,则触发事件子过程并取消该过程。 您还可以使用并行网关和终止结束事件。 但我会推荐上述方法之一。 There are different ways to model this. You could use an interrupting boundary message receive event and if the extra info wa ...
-
您的解决方案不完善,因为在您调用isCancelled()和调用get()之间可能会发生取消,这很少会导致异常。 更好的方法是捕获CancellationException并处理它。 Your solution is imperfect since cancellation could occur between the time you call isCancelled() and the time you call get() which would, rarely, still result in t ...
-
我不确定回答我自己的任务是否正常,所以我不会将其标记为答案,也许有人想出一个更好的解决方案:P 首先,这里是生产者代码: static async Task StartAsync() { using (var queue = new SendMessageQueue(10, new SendMessageService())) using (var timeoutTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(4. ...
-
URLSessionUploadTask立即自动取消(URLSessionUploadTask getting automatically cancelled instantly)[2023-08-06]
经过6天不间断的挣扎,以及谷歌搜索不停的解决方案后,我很高兴地说我终于明白了。 转向我们,无论出于什么神秘的原因, uploadTask(with:from:completionHandler)的from:参数uploadTask(with:from:completionHandler)都不能为零。 尽管参数被标记为可选Data ,但它在缺失时会立即被取消。 这可能是Apple方面的一个错误,当我无法使其工作时我打开了一个错误,因此我将使用这些新信息更新我的错误报告。 话虽如此,我所要做的就是更新我的bui ...