线程返回值
子线程使用pthread_exit()
向调用线程返回数值,函数原型:void pthread_exit(void *retval);
调用线程使用函数pthread_join()
的第二个参数void **
接收返回值。函数原型:int pthread_join(pthread_t thread, void **retval);
例子:
main中创建一个线程pthTextCode,在新线程中用pthread_exit()返回一个值,main接收这个值并打出来。
main.c:
void *retval;
//...
retval = NULL;
ret = pthread_create(&pthTextCode,NULL,pthTextCode_run,NULL);
//...
pthread_join(pthTextCode,&retval);
printf("retval from textCode thread: %d\n",*(int*)(retval));
free(retval);
//...
pthTextCode.c
int *retval;
retval = NULL;
//...
retval = (int *)malloc(sizeof(int));
*retval = 1;
pthread_exit((void *)retval);
结果:
main thread wait textCode thread working...
[Switching to Thread 0xb7fe7b70 (LWP 9629)]
Breakpoint 2, pthTextCode_run (arg=0x0) at pthTextCode.c:103
103 retval = (int *)malloc(sizeof(int));
Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.192.el6.i686
(gdb) n
104 *retval = 1;
(gdb) p retval
$1 = (int *) 0xb7400488
(gdb) p &retval
$2 = (int **) 0xb7fe7378
(gdb) c
Continuing.
[Switching to Thread 0xb7fe88d0 (LWP 9626)]
Breakpoint 1, main () at main.c:78
78 pthread_join(pthTextCode,&retval);
(gdb) n
[Thread 0xb7fe7b70 (LWP 9629) exited]
79 printf("retval from textCode thread: %d\n",*(int*)(retval));
Missing separate debuginfos, use: debuginfo-install libgcc-4.4.7-17.el6.i686
(gdb) p retval
$3 = (void *) 0xb7400488
(gdb) p &retval
$4 = (void **) 0xbffff1e4
(gdb) p *retval
Attempt to dereference a generic pointer.
(gdb) n
retval from textCode thread: 1
83
可以看出main中的void *reaval
和pthTextCode
中的int *retval
,两个retval
都指向同一个地址,即线程pthTextCode
malloc出来的内存地址。
重复引用头文件
相关错误: /tmp/XXX.o:(.bss+0x0): multiple definition
通常:
#ifndef XX_H
#define XX_H
/* ... */
#endif //XX_H
用于防止头文件被重复引用,造成编译效率的低下。但它不能保证头文件里的东西就是唯一的。比如在头文件定义全局变量,这份头文件又被多个c源文件引用,那么编译器就会提示你重复定义。
下面的例子中number.h是这样的:
#ifndef NUMBER_H
#define NUMBER_H
#define LEN 1000010
enum BOOL{False,True};
typedef enum BOOL bool;
bool num_vis[LEN] = {0};
int prime_cnt;
int prime_number[LEN][2];
void get_prime();
#endif //NUMBER_H
test.c、number.c都include了number.h,编译:
[edemon@CentOS tmp]$ gcc test.c number.c -o exe
/tmp/ccJStRc2.o:(.bss+0x0): multiple definition of `num_vis'
当我们将定义改成声明,这个错误就消失了。
二进制文件I/O
用fwrite()将2,3,5,7,11写入文件key中,然后通过fread读取。
main.c:
#include "../pthTextRW.h"
//...
int main(){
prime_stack_cnt = 5;
prime_stack[0] = 2;
prime_stack[1] = 3;
prime_stack[2] = 5;
prime_stack[3] = 7;
prime_stack[4] = 11;
prime_write();
prime_read();
return 0;
}
pthTextRW.c中的读写函数:
void prime_write(){
FILE *key_p = NULL;
int i;
key_p = fopen(key_path,"w");
if(key_p == NULL){
perror("key path w fopen: ");
exit(1);
}
for (i=0; i<prime_stack_cnt; i++){
fwrite(&prime_stack[i],sizeof(int),1,key_p);
}
fclose(key_p);
}
void prime_read(){
FILE *key_p;
int i;
key_p = fopen(key_path,"r");
i=0;
if(key_p == NULL){
perror("key_p r fope: ");
exit(1);
}
while(!feof(key_p)){
fread(&prime_stack[i++],sizeof(int),1,key_p);
}
fclose(key_p);
int j;
for (j=0; j<i; j++){
printf("%d ",prime_stack[j]);
}
puts("");
}
用vim打开fwrite生成的二进制文件:
^B^@^@^@^C^@^@^@^E^@^@^@^G^@^@^@^K^@^@^@$
最后一个特殊的字符$
是行尾锚定:
$ DO 0x24 36 DOLLAR SIGN
表示一行的终结。
其他字符在vim
的help digraph-table
能够找到:
digraph-table
char digraph hex dec official name
^@ NU 0x00 0 NULL (NUL)
^A SH 0x01 1 START OF HEADING (SOH)
^B SX 0x02 2 START OF TEXT (STX)
^C EX 0x03 3 END OF TEXT (ETX)
^D ET 0x04 4 END OF TRANSMISSION (EOT)
^E EQ 0x05 5 ENQUIRY (ENQ)
^F AK 0x06 6 ACKNOWLEDGE (ACK)
^G BL 0x07 7 BELL (BEL)
^H BS 0x08 8 BACKSPACE (BS)
^I HT 0x09 9 CHARACTER TABULATION (HT)
^@ LF 0x0a 10 LINE FEED (LF)
^K VT 0x0b 11 LINE TABULATION (VT)
^L FF 0x0c 12 FORM FEED (FF)
^M CR 0x0d 13 CARRIAGE RETURN (CR)
^N SO 0x0e 14 SHIFT OUT (SO)
vim显示的是字符结果,特殊字符对应的十进制值刚好是2, 3, 5, 7, 11
EOF的值通常设置成-1
feof()
返回的是最后一次读操作完毕后的内容,只有多读才能到达EOF。也就是说,上面的prime_read()
函数读取的内容是多于输入内容的。实践操作后,我发现他总是多读一个0: 2 3 5 7 11 0
工程地址:https://github.com/theArcticOcean/CLib/tree/master/myLocker