关闭

【github myLocker】线程返回值,重复引用头文件,二进制文件I/O

标签: 线程二进制c
355人阅读 评论(0) 收藏 举报
分类:

线程返回值

子线程使用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        free(buff);

可以看出main中的void *reavalpthTextCode中的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'
/tmp/ccWyM4rc.o:(.bss+0x0): first defined here

当我们将定义改成声明,这个错误就消失了。

// number.h
bool num_vis[LEN];

二进制文件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
表示一行的终结。
其他字符在vimhelp 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/myLocker

0
0
查看评论
发表评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场

Linux网络编程——I/O复用之poll函数

一、回顾前面的select select优点: 目前几乎在所有的平台上支持,其良好跨平台支持也是它的一个优点 select缺点: 1.每次调用 select(),都...
  • lianghe_work
  • lianghe_work
  • 2015-06-17 15:09
  • 5275

Java中的I/O流及利用I/O流实现文件复制功能

Java中的I/O流及利用I/O流实现文件复制功能 一、I/O流的概念        1、 什么是I/O? 硬件层面:I/O(input/output),即输入/输出。每个设备都会有一个专用的I...
  • BlueSky_USC
  • BlueSky_USC
  • 2016-11-25 18:49
  • 1851

linux文件操作-标准I/O操作--fgets与gets

fgets与gets 1 gets介绍 [函数原型]                #include        ...
  • u012606927
  • u012606927
  • 2013-12-28 19:57
  • 2152

C#--I/O流操作二进制文件之BinaryWriter类和BinartReader类

使用I/O流操作二进制文件时要用到BinaryWriter类和BinartReader类 1.BinaryWriter类 BinaryWriter类以二进制形式将基元类型写...
  • u010792238
  • u010792238
  • 2014-06-10 17:30
  • 2942

java 二进制 文件I/O 2进制和10进制的转换 程序实现 以及移位

1详细二进制 (主要是用于基本i/o流) #二进制: 1、计算机内部都是2进制 2、数组和ArrayList的区别:ArrayLlsit里面有算法(通用算法,只有当通用算法不行的时候,可以自己...
  • u012429555
  • u012429555
  • 2016-05-04 19:45
  • 992

防止头文件被重复引用

一、下划线“__”属于编程风格的内容,对程序没有影响。不用下划线也可以,用几个下划线也由个人习惯。 二、其实质是一个宏名。由此我们可以防止发生重复定义或声明。 假设你的头文件名为head....
  • qq1987924
  • qq1987924
  • 2012-07-23 20:40
  • 6811

高质量C++编程(一)防止头文件重复引用

【规则1-2-1】为了防止头文件被重复引用,应当用ifndef/define/endif结构产生预处理块。   一、为什么会出现头文件被重复引用的问题      在一个CPP文件中,...
  • Andeewu
  • Andeewu
  • 2013-06-16 23:03
  • 2708

#ifndef/#define/#endif 防止该头文件被重复引用

转载自:http://blog.csdn.net/abc5382334/article/details/18052757    想必很多人都看过“头文件中的 #ifndef/#define/#e...
  • sinat_33718563
  • sinat_33718563
  • 2017-05-26 11:03
  • 88

c++ 避免头文件重复引用 (pragma once与 #ifndef的区别)

如何防止头文件被重复引用? 有两种方法: 1.方法一:  使用:   # pragma  once  2>方法二: 使用:  # ifndef      #defin...
  • ZHL30041839
  • ZHL30041839
  • 2014-07-12 18:43
  • 1482

头文件重复引用

#include文件的一个不利之处在于一个头文件可能会被多次包含,为了说明这种错误,考虑下面的代码: #include "x.h" #include "x.h" 显然,这里文件x.h被包...
  • luojinping
  • luojinping
  • 2011-09-30 09:27
  • 465
    个人资料
    • 访问:327280次
    • 积分:8806
    • 等级:
    • 排名:第2521名
    • 原创:574篇
    • 转载:13篇
    • 译文:0篇
    • 评论:36条
    我的链接
    最新评论