strtok的功能和多线程 [英] strtok function and multithreading
问题描述
我读了有关的strtok(字符* S1,字符* S2)及其实施很多东西。但是,我仍然无法理解是什么使一个危险的功能多线程程序中使用。可有人请给我一个多线程程序的一个例子,解释这个问题呢?请不就是我要找显示我在哪里,问题就出现了一个例子。
I read a lot of stuff about strtok(char* s1, char* s2) and its implementation. However, I still can not understand what makes it a dangerous function to use in multi-threaded program. Can somebody please give me an example of a multi-threaded program and explain the issue there? Please not that I am looking for an example that shows me where the problem arises.
PS:strtok的(字符* S1,字符* S2)是C标准库的一部分。
ps: strtok(char* s1, char* s2) is part of the C standard library.
推荐答案
下面是一个具体的例子:
Here is a concrete example:
首先假设你的程序是多线程的,并且在执行一个线程,下面code运行:
Suppose first that your program is multi-threaded, and in one thread of execution, the following code runs:
char str1[] = "split.me.up";
// call this line A
char *word1 = strtok(str1, "."); // returns "split", sets str1[5] = '\0'
// ...
// call this line B
char *word2 = strtok(NULL, "."); // we hope to get back "me"
和在另一个线程,以下code运行:
And in another thread, the following code runs:
char str2[] = "multi;token;string";
// call this line C
char *token1 = strtok(str2, ";"); // returns "multi", sets str2[5] = '\0'
// ...
// call this line D
char *token2 = strtok(NULL, ";"); // we hope to get back "token"
问题的关键是,我们真的不知道会在字词2
和 token2
什么:
如果该命令的顺序(A),(B),(C),(D)上运行,那么我们会得到我们想要的东西。
If the commands are run in the order (A), (B), (C), (D), then we will get what we want.
但如果说,命令中的顺序运行(A),(C),(B),(D),然后命令(B)将搜索。
在记号;字符串
!这是因为 NULL
第一个参数的命令(B)告诉 strtok的
继续在搜索的最后一个非 - NULL
搜索字符串它被通过,因为命令(C)已经运行, strtok的
将使用 STR2
。
But if, say, the commands run in the order (A), (C), (B), (D), then command (B) will search for a .
delimeter in "token;string"
! This is because the NULL
first argument to command (B) tells strtok
to continue searching in the last non-NULL
search string it was passed, and because command (C) has already run, strtok
will use str2
.
然后命令(B)将返回标记;串
,同时设置一个搜索到的 NUL <新起始字符/ code>终止在
STR2
的结束。然后命令(D)会认为这是寻找一个空字符串,因为这将开始其在的STR2
NUL $ C $搜索C>终止,所以会返回
NULL
以及
Then command (B) will return token;string
, at the same time setting the new starting character of a search to the NUL
terminator at the end of str2
. Then the command (D) will think it is searching an empty string, because it will begin its search at str2
's NUL
terminator, and so will return NULL
as well.
即使你把命令(A)和(B)紧挨着对方,并命令(C)和(D)紧挨着对方,也不能保证(B)会之后立即执行( A)之前是(C)或(D)等。
Even if you place commands (A) and (B) right next to each other, and commands (C) and (D) right next to each other, there is no guarantee that (B) will be executed right after (A) before either (C) or (D), etc.
如果你建立某种形式的互斥体或替代后卫的保护了 strtok的
的功能,并且只调用 strtok的
从已取得的锁的线程表示互斥,那么 strtok的
可以放心使用。但是,它可能只是为了更好地使用线程安全的 strtok_r
正如其他人说。
If you create some sort of mutex or alternate guard to protect the use of the strtok
function, and only call strtok
from a thread which has obtained a lock on said mutex, then strtok
is safe to use. However, it is probably better just to use the thread-safe strtok_r
as others have said.
编辑:还有一个问题,就是别人没提,即 strtok的
修改,并可能使用全局(或静态的,无论)变量,并在可能-不是线程安全的方式这样做,所以即使你不靠重复调用 strtok的
来得到连续的令牌相同的字符串,也未必是安全的使用它在多线程环境中无人看守,等。
There is one more issue, that nobody else has mentioned, namely that strtok
modifies and potentially uses global (or static, whatever) variables, and does so in a probably-not-thread-safe way, so even if you don't rely on repeating calls to strtok
to get successive "tokens" from the same string, it may not be safe to use it in a multi-threaded environment without guards, etc.
这篇关于strtok的功能和多线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!