帐前卒专栏

code, software architect, articles and novels.
代码,软件架构,博客和小说

if you use const variable to define an array out of main, like that:
1
2
3
4
5
6
7
8
9
10
11
12
#include<stdio.h>

const int MAX= 100010;
char s[MAX];
int main(){

while(fgets(s,MAX,stdin) != NULL){
puts(s);
}
return 0;

}

gcc will report : Error: variably modified ‘s’ at file scope. But if you use #define, it will be ok. like that:

1
2
3
4
5
6
7
8
9
10
11
12
#include<stdio.h>

#define MAX 100010
char s[MAX];
int main(){

while(fgets(s,MAX,stdin) != NULL){
puts(s);
}
return 0;

}

If you do not want to use #define macro, and you will use a small array, you can use a const variable to define the array size, like that:

1
2
3
4
5
6
7
8
9
10
11
12
13
#include<stdio.h>

//#define MAX 100010
//char s[MAX];
int main(){
const int MAX= 30;
char s[MAX];
while(fgets(s,MAX,stdin) != NULL){
puts(s);
}
return 0;

}

But if you will allocate a big array in main function, gcc will report a warning ⚠️ overflow in implicit constant conversion

My signature:

http://en.wikipedia.org/wiki/Wikipedia:ASCII_art_conversion_tool

there is a good tool for converting bitmap to ascii.

[codesyntax lang=“c” tab_width=“2”]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
/*

ascii art conversion utility
Copyright 2001 Damian Yerrick

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including

without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.

*/
/*

ascii.c converts a bitmap (in .bmp or .pcx format) to ASCII art.
It treats the least significant bitplane as a monochrome image,
making 0 dark and 1 light. Each character sent to stdout represents
a 2x2 cell in the bitmap.

It uses the Allegro library to read the bitmap. Allegro is a
multimedia library that has been ported to POSIX+X11, DOS, Windows,
BeOS, and Mac OS. There are library extensions that allow Allegro
to handle other file formats such as PNG.
http://alleg.sourceforge.net/allegro/

Because of the simple design of the program, it is also extremely
easy to port to other imaging APIs.

Compilation on DOS:
gcc -Wall -O ascii.c -lalleg -o ascii.exe
Compilation on Linux:
gcc -Wall -O ascii.c `allegro-config --libs` -o ascii

*/

#include <allegro.h>
#include <stdio.h>
#include <stdlib.h>

/* the following characters' glyphs represent 2x2 pixel tiles */
const char tiles[16] = {
'M', 'P', 'V', '"',
'b', ')', '\\','\'',
'd', '/', '(', '`',
'a', '.', ',', ' '
};

int main(int argc, char **argv)
{
BITMAP *bmp;
int y;

install_allegro(SYSTEM_NONE, &errno, atexit);

if(argc != 2)
{
allegro_message("usage: ascii foo.bmp\n");
return EXIT_FAILURE;
}

/* if you've installed Allegro library extensions for
other bitmap formats, register their functions here */

bmp = load_bitmap(argv[1], NULL);
if(bmp == NULL)
{
allegro_exit();

fprintf(stderr, "ascii Error: could not load bitmap `%s'\n", argv[1]);
return EXIT_FAILURE;
}

for(y = 0; y < bmp->h; y += 2)
{
int x;
for(x = 0; x < bmp->w; x += 2)
{
int c = 0;
if(getpixel(bmp, x, y ) & 1)
c |= 8;
if(getpixel(bmp, x+1, y ) & 1)
c |= 4;
if(getpixel(bmp, x, y+1) & 1)
c |= 2;
if(getpixel(bmp, x+1, y+1) & 1)
c |= 1;
putchar(tiles[c]);
}
putchar('\n');
}
destroy_bitmap(bmp);

return EXIT_SUCCESS;
} END_OF_MAIN();

The ASCII art is the art of using characters to create a “picture”. like:

the ASCII is:

The scale of type int is[231,2311][-2^{31},2^{31}-1], and it is a little more than
[2109,2109][-2*10^{9},2*10^{9}]. and the scale of long long type is [263,2631][-2^{63},2^{63}-1], and it is a little less than [1019,1019][-10^{19},10^{19}]

int i = 10610610^{6}* 10^{6}; // this is wrong!!!

long long j = 10910910^{9}* 10^{9} ; // this is correct!

printf(“%d”,i);

printf(“%lld”,j);

int some platform or some compiler, long type is equal to int type. They are 32 bits. But long long type is 64 bits in linux.

use #define to declare a const, like this( if the number is too big):

1
#define BIG (9000000000000000000)ULL // this is unsigned long long

** 1、 ** 将文 件checkout到本地目录

** svn checkout ** path(path是服务器上的目录)
例如: svn checkout svn 😕/ 192.168 . 1.1 /pro/domain
简写: svn co

** 2、 ** 往版 本库中添加新的文件

** svn ** ** add ** file
例如: svn add test.php(添加test.php)
svn add *.php(添加当前目录下所有的php文件)

** 3、 ** 将改 动的文件提交到版本库

** svn commit ** -m “LogMessage“ [ -N ] [ --no-unlock ] PATH (如果选择了保持锁,就使用–no-unlock开关)
例 如: svn commit -m “add test file for my test“ test.php
简写: svn ci

** 4、 ** 加锁 /解锁

** svn lock ** -m “LockMessage“ [ --force ] PATH
例如: svn lock -m “lock test file“ test.php
** svn unlock ** PATH

** 5、 ** 更新 到某个版本

** svn update -r ** m path
例如:
svn update如果后面没有目录,默认将当前目录以及子目录下的所有文件都更新到最新版本。
svn update -r 200 test.php(将版本库中的文件test.php还原到版本200)
svn update test.php(更新,于版本库同步。如果在提交的时候提示过期的话,是因为 ** 冲突,需要先update,修改文件 ** ,
然后清除 ** svn resolved ** ,最后再提交 commit)
简写: svn up

** 6、 ** 查看 文件或者目录状态

1) ** svn status ** path
(目录下的文件和子目录的状态,正常状态不显示)
【?: 不在 svn 的控制中;M:内容被修改;C:发生冲突;A:预定加入到版本库;K:被锁 定】
2) ** svn status -v ** path
(显示文件和子目录状 态)
第一列保持相同,第二列显示工作版本号,第三和第四列显示最后一次修改的版本号和修改人。
注: svn status、 svn diff和 svn revert这三条命令在没有网络的情况下也可以执行的,原因是 svn 在本地的.
svn 中保留了 本地版本的原始拷贝。
简写: svn st

** 7、 ** 删除 文件

** svn delete ** path -m “delete test fle“
例 如: svn delete svn 😕/192.168.1.1/pro/domain/test.php -m “delete test
file”
或者直接 svn delete test.php 然后再 svn ci -m ‘delete test file‘,推荐使用这种
简写: svn (del, remove, rm)

** 8、 ** 查看 日志

** svn log ** path
例如: svn log test.php 显示这个文件的所有修改记录,及其版本号的变化

** 9、 ** 查看 文件详细信息

** svn info ** path
例如: svn info test.php

** 10、 ** 比 较差异

** svn diff ** path(将修改的文件与基础版本比较)
例如: svn diff test.php
** svn diff ** -r m:n path(对版本m和版本n比较差异)
例 如: svn diff -r 200:201 test.php
简写: svn di

** 11、 ** 将 两个版本之间的差异合并到当前文件

** svn merge -r ** m:n path
例如: svn merge -r 200:205 test.php(将版本200与205之间的差异合并到当前文件,但是一般都会产生冲突,需要处理一下)

** 12、 ** SVN 帮助

** svn help
svn help ci **

——————————————————————————

以上是常用命令,下面写几个不经常用的

——————————————————————————

** 13、 ** 版 本库下的文件和目录列表

** svn list ** path
显示path目录下的所有属于版本库的文件和 目录
简写: svn ls

** 14、 ** 创 建纳入版本控制下的新目录

** svn mkdir ** : 创建纳入版本控制下的新目录。
用法: 1、mkdir PATH…
2、mkdir URL…
创建版本控制的目录。
1、每一个以工作副本 PATH 指定的目录,都会创建在本地端,并且加入新增
调度,以待下一次的提交。
2、每个以URL指定的目录,都会透过立即提交于仓库中创建。
在 这两个情况下,所有的中间目录都必须事先存在。

** 15、 ** 恢 复本地修改

** svn revert ** : 恢复原始未改变的工作副本文件 (恢复大部份的本地修改)。revert:
用法: revert PATH…
注意: 本子命令不会存取网络,并且会解除冲突的状况。但是它不会恢复
被删除的目录

** 16、 ** 代 码库URL变更

** svn switch (sw): ** 更新工作副本至不同的URL。
用法: 1、switch URL [PATH]
2、switch –relocate FROM TO [PATH…]

1、更新你的工作副本,映射到一个新的URL,其行为跟“ svn update”很像,也会将
服务器上文件与本地文件合并。这是将工作副本对应到同一仓库中某个分支或者标记的
方法。
2、改写工 作副本的URL元数据,以反映单纯的URL上的改变。当仓库的根URL变动
(比如方案名或是主机名称变动),但是工作副本仍旧对映到同一仓库的同 一目录时使用
这个命令更新工作副本与仓库的对应关系。

** 17、 ** 解 决冲突

** svn resolved: ** 移除工作副本的目录或文件的“冲突”状态。
用 法: resolved PATH…
注意: 本子命令不会依语法来解决冲突或是移除冲突标记;它只是移除冲突的
相关文件,然后让 PATH 可以再次提交。

** 18、 ** 输 出指定文件或URL的内容。

** svn ** ** cat ** 目标[@版本]…如果指定了版本,将从指定的版本开始查找。
svn cat -r PREV filename > filename (PREV 是上一版本,也可以写具体版本号,这样输出结果是可以提交的)

禁闭岛

  • ** 国家/地区: ** 美国
  • ** 类型: ** 惊悚 / 剧情 / 悬疑
  • ** 片长: ** 138 min
  • ** 分级: ** USA:R
  • ** 对白语言: ** 英语
  • ** 发行公司: ** 派拉蒙影业公司
  • ** 官方网站: ** Paramount Pictures [us]

live as a monster, or die as a good man.(像怪物一样活着,还是像好人一样死去?)这句话是主角最后的一句话。让我想起了
《飞跃疯人院》,感觉情节其实很相似。首先,没有人能评判谁是精神病人,也没有人知道他们两者到底有何区别。想起曾有精神病院司机把一群正常人带入精神病院的有趣笑话
,传说某个智商极高的人在21天后才被推断出没有精神病。

对于这个影片,其实怎么看都是对的。也就是说可以看成是真正的执法官调查阿什精神病院的故事。也可以看成一个疯子虚构出自己的办案经历。这让我想起《罗生门》中的情节
。罗生门中其实就是一个武士杀死了另外一个武士。结果经历过此事的所有人的描述各不相同。也就印证了人脑其实是反映当时经历的工具,并且这个工具并不像摄像机那样精确
。罗生门只不过让这种不精确扩大化已而。看完罗生门之后,人整个就迷糊了。里面没有任何情节不合乎逻辑,每个人都是正常人并且回忆着非常有逻辑的事情。不过我看完《禁
闭岛》之后,更加倾向于前者。虽然我也不知道影片的结尾主角为何可以说出自己的准确杀人经历。但是有几点各自矛盾:1.主角是岛上最危险的犯人。为何没有脚镣?2.主
角为何可以和护工穿同样的白衣?3.主角为何可以和主治医生睡在一间房里?4.主角为何能大摇大摆的走到C病房。并且警卫不认识他,另外警卫也不认识查理(后自称为西
恩医生的人)?5.主角可以和典狱长去兜风。6.如果主角的配枪开始就是假的,警卫为何要解除他的配枪?8.主角能逛到任何角落。9.灯塔里不觉得太空旷了吗?如此空
的地方为何有配枪守卫(虽然枪中没有子弹)和铁网?10.审问精神病人时为何那人写下"Run"?那么最后一句话:live as a monster, or
die as a good man.便可以理解为:与其让他们把自己当做试验品成为怪物,还不如在正常理智情况下死去,或者死去之前再也不会伤害谁(也就是切除大脑
额叶)。另外作为“僵尸”的他,也可以回归到大陆,而无需在禁闭岛中。所以也是所谓的"逃离"。

另外也可以做第二种解释:1.影片主角杰克在第一次看到自己妻子的时候,先是妻子背部烧焦,后是腹部流血。为何流血,不正是暗示被枪杀吗?那么情节其实是主角先枪杀自
己的妻子,然后再将其烧死。并且不承认自己杀人。2.为何偏头痛,并且老是能看到已故的妻子?3.额头为何有伤疤,是大脑做过手术的证据吗?4.为何有主角的入籍档案
(类似关押犯人的档案)?5.为何有那三个孩子的照片?并且为啥认定他有三个孩子而不是一个?6.瑞秋、老鼠、山洞、火堆、审讯,所有的一切都是自己虚构出来的。并且
按照自己的逻辑演绎。一切的一切都是虚构。最终主角接受了现实并且选择了自己的逃离方式。live as a monster, or die as a good
man.就可以解释为自己是杀妻杀人的精神病凶手(monster)度过余生,或者以死赎罪死得其所(至少切除额叶便失去了自我意思)。选择后者,至少自己(自我意思
)已经逃离了禁闭岛。此句也可解释为是像众人眼中的疯子,还是应该如同尸死走肉(切除额叶的人只有生存的本能,也不会再去伤害别人)?

不过不管怎么说,影片的导演的确是不希望我们看得明白。至少导演在两种解释中都自圆其说同时也都漏洞百出,另外导演也不断的从现实、梦境、真实、谎言中切换。让观者不
知谁真谁假,孰是孰非。

不过导演貌似是想将下面的想法告诉观者:

1.请大家思考切除大脑额叶是对还是错?live as a monster, or die as a good man?

2.请大家思考训练将参加战争的人是对是错。live as a monster, or die as a good man?

3.请大家思考战争中杀人是对是错?live as a monster, or die as a good man?

4.请大家思考以暴制暴是对是错?live as a monster, or die as a good man?

5.请大家思考以死谢罪,还是以生赎罪?live as a monster, or die as a good man?

不过观后感千人千面,各有不同,如同《罗生门》。

因为使用的是ubuntu, 安装相当简单,去软件管理器中输入svn就可以。或者使用

$ sudo apt-get install subversion

其实也没有怎么按照svn的安装流程走,那样的话需要添加新的用户,用户组。安全系数高一些。下面是自己的流程:

首先建一个svn目录,mkdir /home/cc/svn

在此目录下创建你自己的代码目录:

cd /home/cc/svn svnadmin create trunk //然后启动svn svnserve -d
–root=/home/cc/svn

如果想在trunk之下创建其他目录,可以直接使用mkdir director的方法。之后去其他机器使用svnclient.也可以使用刚才的apt-get
install subversion的方式。

svnserve.conf:12: Option
expected,产生的原因是没有顶格写。例如在/home/cc/svn/trunk/conf/svnserve.conf中:

[general] anon-access = none ### 这里auth-access的写法是错误的。 auth-access = write ###
这样写才是正确的 auth-access = write

svn : No access allowed to this repository

首先要把 svnserve.conf中的password-db = passwd注释去掉。然后在passwd文件中添加:

[users] cc = 123

在authz中添加:

[groups] ### 这里是建立一个组 user = cc,aa,bb,dd ###
这里repository:后添加的是相对路径,例如我的路径/home/cc/svn/trunk在这里就是/trunk [repository:/trunk]

这里@user是某一个组的权限 @user = rw ### 这是所有用户的权限 * = r

以后使用svn需要输入–username=cc --password=123

Authorization failed

这里是因为在authz中的路径可能设置有问题(repository:之后的那个路径,那里面的路径全部都是相对路径),或者是命令没有顶格写。passwd,
authz, svnserve.conf中的所有命令必须是顶格写的。

下面是远程机器使用svn导入项目:

svn import  [本地目录] svn://[ip]/trunk -m "import project"即可.例如我的是 svn import
~/code/cnode svn://192.168.1.22/trunk -m “import”  --username=cc
–password=123

这里要注意的是svn会将本地目录之下的所有东西都按照相同的组织方式放入到trunk.所有最好导入工程根目录。

贴一下写好的配置文件,这里我的trunk是pddms: authz

This file is an example authorization file for svnserve. ### Its format is

identical to that of mod_authz_svn authorization ### files. ### As shown below
each section defines authorizations for the path and ### (optional) repository
specified by the section name. ### The authorizations follow. An authorization
line can refer to: ### - a single user, ### - a group of users defined in a
special [groups] section, ### - an alias defined in a special [aliases]
section, ### - all authenticated users, using the ‘$authenticated’ token, ###

  • only anonymous users, using the ‘$anonymous’ token, ### - anyone, using the
    ‘*’ wildcard. ### ### A match can be inverted by prefixing the rule with ‘~’.
    Rules can ### grant read (‘r’) access, read-write (‘rw’) access, or no access

(‘’). [aliases] # joe = /C=XZ/ST=Dessert/L=Snake City/O=Snake Oil,

Ltd./OU=Research Institute/CN=Joe Average [groups] harry_and_sally =
cc,aa,bb,dd # harry_sally_and_joe = harry,sally,&joe [/] cc = rw # &joe = r #

  • = [repository:/pddms] @harry_and_sally = rw * = r

passwd:

This file is an example password file for svnserve. ### Its format is

similar to that of svnserve.conf. As shown in the ### example below it
contains one section labelled [users]. ### The name and password for each user
follow, one account per line. [users] cc = 123 aa = 123 # harry = harryssecret

sally = sallyssecret

svnserve.conf

This file controls the configuration of the svnserve daemon, if you

use it to allow access to this repository. (If you only allow ### access
through http: and/or file: URLs, then this file is ### irrelevant.) ### Visit
http://subversion.tigris.org/ for more information. [general] ### These
options control access to the repository for unauthenticated ### and
authenticated users. Valid values are “write”, “read”, ### and “none”. The
sample settings below are the defaults. anon-access = none auth-access = write

The password-db option controls the location of the password ### database

file. Unless you specify a path starting with a /, ### the file’s location is
relative to the directory containing ### this configuration file. ### If SASL
is enabled (see below), this file will NOT be used. ### Uncomment the line
below to use the default password file. password-db = passwd ### The authz-db
option controls the location of the authorization ### rules for path-based
access control. Unless you specify a path ### starting with a /, the file’s
location is relative to the the ### directory containing this file. If you
don’t specify an ### authz-db, no path-based access control is done. ###
Uncomment the line below to use the default authorization file. authz-db =
authz ### This option specifies the authentication realm of the repository.

If two repositories have the same authentication realm, they should

have the same password database, and vice versa. The default realm ### is
repository’s uuid. realm = pddms_a [sasl] ### This option specifies whether
you want to use the Cyrus SASL ### library for authentication. Default is
false. ### This section will be ignored if svnserve is not built with Cyrus

SASL support; to check, run ‘svnserve --version’ and look for a line

reading ‘Cyrus SASL authentication is available.’ # use-sasl = true ### These
options specify the desired strength of the security layer ### that you want
SASL to provide. 0 means no encryption, 1 means ### integrity-checking only,
values larger than 1 are correlated ### to the effective key length for
encryption (e.g. 128 means 128-bit ### encryption). The values below are the
defaults. # min-encryption = 0 # max-encryption = 256

when you use double type to count, it will be dangerous. see like that

[codesyntax lang=“c” tab_width=“2”]

1
2
3
4
5
6
7
8
#include<stdio.h>
int main(){
double i;
for(i=0; i != 5; i++){
printf("%lf ",i);
}
return 0;
}

it will never stop, because the condition of i != 5 will never satisfied. If you want to count, using int type. When you compare two double type number, you should use fabs(a-b) < 0.001, 0.001 is threshold. Sometimes, double is not precision. macro is a great tool, but it is also dangerous. I often forget the language of define. The correct language is :

#define

#if defined

#if !defined

#ifndef

#ifdef

#endif

compile .c file with math lib in linux. It will be like that: cc test.c -o test -lm

stdio redirect to file use freopen() function. like that:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include&lt;stdio.h&gt;
// don't write freopen here, it will be some compile error.
//freopen("test.in","r",stdin);
//freopen("test.out","w",stdout);
int main(){
int n,i;
#if defined REDIRECT
freopen("test.in","r",stdin);
freopen("test.out","w",stdout);
#endif
scanf("%d",&amp;n);
for(i = 0; i &lt; n; i++){
printf("%d ",i);
}
return 0;
}

if you want redirect to file, use the code and compile it with -D REDIRECT. cc test.c -o test -D REDIRECT

If you want to use struct FILE to do the same thing:

[codesyntax lang=“c” tab_width=“2”]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include&lt;stdio.h&gt;
#include&lt;math.h&gt;
int main(){
FILE * fin, *fout;
fin = fopen("z.in","rb");
fout = fopen("z.out","wb");
int n;
#ifdef REDIRECT
#define fin stdin
#define fout stdout
#endif

fscanf(fin,"%d",&amp;n);
fprintf(fout,"%d,%lf",n,sqrt(n));
fclose(fin);
fclose(fout);
return 0;
}

try cc t3.c -o t3 -lm -D REDIRECT and cc t3.c -o t3 -lm

Singleton is a pattern in Software Architecture. It is used to create a instance and there will be only one instance in system at any time. If you want to write this pattern in a file, it will be like that:

[codesyntax lang=“cpp” tab_width=“2”]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include &lt;iostream&gt;
using namespace std;
/* ==========================
* Program name:
* Author: chico chen
* Email: chillycreator @t gmail.com
* Purpose: this class is testing singleton pattern in
* Software Architecture.
* ========================== */

class Singleton {
private:
static Singleton* _instance;
Singleton(){}
public:
static Singleton* Instance();
};
Singleton* Singleton::_instance = NULL;
Singleton* Singleton::Instance() {
if (_instance == NULL) {
_instance = new Singleton();
cout &lt;&lt;"new Singleton"&lt;&lt;endl;
}
return _instance;
}

int main() {
cout &lt;&lt; "Hello world!" &lt;&lt; endl;
Singleton *s1 = Singleton::Instance();
Singleton *s2 = Singleton::Instance();
Singleton *s3 = Singleton::Instance();
Singleton *s4 = Singleton::Instance();
return 0;
}

If you want write this pattern into different files, it will has Singleton.h Singleton.cpp and other files like that:

Read more »

我至今不知道为啥出现的这种情况。不过很有可能是弹出提示后出现的卡机现象。首先下载一个python IDLE 3或者2.6什么的,然后打开,写入最简单的一行p
rint(“hello”),当输入完")"之后,就完全不能动了,输入回车,点击鼠标均无效果。不过使用Alt+tab切换一下窗口就可以了。不知道这是否是一项不
错的专利,灰常强大!可以有效减少amp.其实我就想要一个可以编辑,然后按下F5或者啥能运行的ide就可以了。结果这都不支持… sigh~Eric4貌似界面
更加华丽,就是不知为何老是错,不知道是否是python版本不兼容的问题…最后只得选用PIDA,短小精悍,这个编python就夠用了。不用emacs的原因
是操作太诡异还不如 vi。最近编c++代码使用codeblocks,感觉这个IDE做得不错,虽然比不上vs2010…另外开头提到的那个卡机现象在k
scope中也会出现。不过这里仅限于ubuntu,它們在centos倒是活得挺好。有人遇到并解决的,请回复…不胜感激,临blog涕零。

这个函数没有什么好说的。其实就两个参数,第一个是线程变量,第二个是线程返回值。其函数原型为:

int pthread_join(pthread_t thread,void** result);

不过查阅许多网上资料,依旧没有使用result这个形参的。一般的使用为pthread_join(thread,NULL);于是自己在想那个NULL能做啥米用
。于是写下下面的代码:

#include <stdio.h> #include <pthread.h> int count =0; // 初始化mutex变量。
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; void * print_count(int);
int main() { const int num = 10; pthread_t threads[num]; int i=0; for(i=0; i<
num; i++){ //第一个参数是pthread_t变量,第二个是pthread_t变量的属性
//第三个是pthread_t需要执行的函数,其函数原型为 // void* (startfun)(void) //
所以传入的是一个返回void的函数(这里当然可以转换) // 并且接受的是void的参数,所以需要把i转换为void *
pthread_create(&threads[i],NULL,print_count,(void*)i); } void* result = NULL;
for(i=0; i < num; i++){ // 这里就是同步得到结果。打印的是线程执行的状态,0为成功。非0失败 printf(“end
%d;/n”,pthread_join(threads[i],&result)); if(result == NULL){
printf(“NULL/n”); } else{ // 这里打印的是pthread_t执行完print_count后返回的结果。
printf(“%x/n”,result); } } return 0; }
//这里返回的类型是void*,因为pthread_create中的函数指针为void* //这里的参数int
i,可有可无,如果没有pthread_create中就使用NULL作为参数。 void * print_count(int i){ // 设置mutex锁
pthread_mutex_lock(&mutex); printf(“thread: %d—> count %d/n”,i,count);
count++; sleep(2); printf(“thread: %d—> count %d/n”,i,count); // 释放锁
pthread_mutex_unlock(&mutex); //这里是返回值, void * result就可以被赋值了…否则为result = NULL
return (void*)count; }

另外值得注意的是pthread_join()中第二个参数不要乱传。如果非NULL,可能造成segment failure.

另外这里如果使用c进行编译可能会有void*
()(int)不能转换为void()(void)的问题。这是因为c
编译器要求太严格了。只好改动函数签名为void *
print_count(void *);之后再进行转换。现在终于知道为啥这么多人都喜欢在linux下使用c了。

0%