免费注册 查看新帖 |

Chinaunix

广告
  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1731 | 回复: 7
打印 上一主题 下一主题

自己思考调用函数会出现这样的问题吗? [复制链接]

论坛徽章:
5
未羊
日期:2014-08-07 15:42:10双子座
日期:2014-09-23 15:42:172015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:55:282022北京冬奥会纪念版徽章
日期:2015-08-10 16:30:32
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-09-16 20:57 |只看该作者 |倒序浏览
在服务器端写了一个日志函数:

参数:fileName是日志文件名称;
        content为写入的内容;
WriteLogFile(char* fileName,char *content)
{
     FILE *fp;
     if((fp=fopen(fileName,"at+"))!=NULL)
     {
            while (*content!='\0')
            {
             fputc(*content,fp);
             content++;
            }
     }
     fclose(fp);
}

在网络编程中我想到这样一个问题:当多个客户端连接到服务器端后,然后给服务器发送信息,只要信息发送的服务器端,那么服务器端就调用上面的日志函数。假如有多个客户端发送的信息同时到达服务器,那么这个函数被同时调用会发生冲突吗?也就是说,服务器端正在将客户端a发送过来的信息写入日志文件中,但还没有写完,这个时候,客户端b也发送过来信息,那么服务器端又要调用日志函数写入日志,可是这个时候,客户端a的信息还有完全写入到日志中。这样会出现写日志冲突吗?或者说会出现错误码?
不知道自己表达清楚了没有。大概意思就是这样。

论坛徽章:
0
2 [报告]
发表于 2009-09-16 21:22 |只看该作者
兄弟,加上写锁就好了。
给你一个代码。

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>

int main(int argc,char* argv[])
{
    int fd;
    struct flock lock;
    int count = 0;

    if(argc != 2)
    {
        printf("Usage: %s filename.\n",argv[1]);
        return 1;
    }

    fd = open(argv[1],O_RDWR);
    if(fd<0)
    {
        printf("Open file failed.\n";
        return 1;
    }
    lock.l_type = F_WRLCK;
   lock.l_whence = 0;   
   lock.l_start = 0;     
    lock.l_len = 0;      

    while(fcntl(fd,F_SETLK,&lock)<0)
    {
       if(errno == EAGAIN||errno ==  EACCES)  //被其他进程加锁了
       {
          if(++count<5)
              sleep(1);  //加锁申请最多持续5s
          else
          {
             fcntl(fd,F_GETLK,&lock);
             printf("id: %ld process find pid %ld process lock the file %s.\n",
                     (long)getpid(),(long)lock.l_pid,argv[0]);
             return 1;
          }
       }
       else
       {
          printf("Error: exec function fcntl failed.\n";
          return 1;
       }
   }
   printf("id: %ld process locked the file.\n",(long)getpid());
   sleep(;   //占用文件的时间,这里可以是对文件的一些操作
   printf("id: %ld process release the file.\n",(long)getpid());
   return 0;
}

[ 本帖最后由 kwaz 于 2009-9-16 21:28 编辑 ]

论坛徽章:
5
未羊
日期:2014-08-07 15:42:10双子座
日期:2014-09-23 15:42:172015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:55:282022北京冬奥会纪念版徽章
日期:2015-08-10 16:30:32
3 [报告]
发表于 2009-09-16 22:47 |只看该作者
非常感谢!革命尚未成功,我还将继续努力!

论坛徽章:
0
4 [报告]
发表于 2009-09-16 23:08 |只看该作者
再说了, 为什么要用fputc? 用 fputs(content, fp) 不是可以吗? 另外, 这个函数设计得很不好, 频繁打开关闭文件非常影响性能.

[ 本帖最后由 ideawu 于 2009-9-16 23:10 编辑 ]

论坛徽章:
5
未羊
日期:2014-08-07 15:42:10双子座
日期:2014-09-23 15:42:172015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:55:282022北京冬奥会纪念版徽章
日期:2015-08-10 16:30:32
5 [报告]
发表于 2009-09-17 09:16 |只看该作者
原帖由 ideawu 于 2009-9-16 23:08 发表
再说了, 为什么要用fputc? 用 fputs(content, fp) 不是可以吗? 另外, 这个函数设计得很不好, 频繁打开关闭文件非常影响性能.

能说的具体一点吗?谢谢!

论坛徽章:
5
未羊
日期:2014-08-07 15:42:10双子座
日期:2014-09-23 15:42:172015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:55:282022北京冬奥会纪念版徽章
日期:2015-08-10 16:30:32
6 [报告]
发表于 2009-09-17 09:18 |只看该作者
原帖由 ideawu 于 2009-9-16 23:08 发表
再说了, 为什么要用fputc? 用 fputs(content, fp) 不是可以吗? 另外, 这个函数设计得很不好, 频繁打开关闭文件非常影响性能.

多个客户端都给服务器传递信息,那如何才能不频繁打开关闭文件从而达到自己的结果?谢谢!

论坛徽章:
0
7 [报告]
发表于 2009-09-17 12:20 |只看该作者
可以把日志功能做成一个单独的进程, 或者线程. 如果是线程, 通过队列和日志的使用者进行通信. 无论进程或者线程, 文件只打开一次, 关闭一次. 而且, 不用文件锁, 但可能需要对队列进行加锁.

或者, 在程序初始化的时候打开文件, 在程序退出时关闭文件.

论坛徽章:
5
未羊
日期:2014-08-07 15:42:10双子座
日期:2014-09-23 15:42:172015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:55:282022北京冬奥会纪念版徽章
日期:2015-08-10 16:30:32
8 [报告]
发表于 2009-09-17 13:24 |只看该作者
原帖由 ideawu 于 2009-9-17 12:20 发表
可以把日志功能做成一个单独的进程, 或者线程. 如果是线程, 通过队列和日志的使用者进行通信. 无论进程或者线程, 文件只打开一次, 关闭一次. 而且, 不用文件锁, 但可能需要对队列进行加锁.

或者, 在程序初始 ...

频繁打开与关闭文件确实不是好办法。
对于你所说的:队列和日志使用者进行通信。我感觉还是比较模糊。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP