stat,string,iconv,socket,sigprocmask,pthread_sigmask

stat,fstat,lstat: 

      int stat(const char *path, struct stat *buf);
       int fstat(int fd, struct stat *buf);
       int lstat(const char *path, struct stat *buf);


struct stat {
               dev_t     st_dev;     /* ID of device containing file */
               ino_t     st_ino;     /* inode number */
               mode_t    st_mode;    /* protection */
               nlink_t   st_nlink;   /* number of hard links */
               uid_t     st_uid;     /* user ID of owner */
               gid_t     st_gid;     /* group ID of owner */
               dev_t     st_rdev;    /* device ID (if special file) */
               off_t     st_size;    /* total size, in bytes */
               blksize_t st_blksize; /* blocksize for file system I/O */
               blkcnt_t  st_blocks;  /* number of 512B blocks allocated */
               time_t    st_atime;   /* time of last access */
               time_t    st_mtime;   /* time of last modification */
               time_t    st_ctime;   /* time of last status change */
           };


stat和lstat的区别:当文件是一个符号链接时,lstat返回的是该符号链接本身的信息;而stat返回的是该链接指向的文件的信息。


string:

<string>文件中:

size_type find_first_not_of (const charT* s, size_type pos = 0) const;
在pos 后搜索字符串,如果找到不匹配字符串s的任意字符 的话, 返回该位置;否则返回string::npos。


size_type find_first_of (const charT* s, size_type pos = 0) const;
与上相反


basic_string substr (size_type pos = 0, size_type len = npos) const;
返回在pos处开始,扩展长度为len的子串,或者直到字符串结尾。

pos等于字符串长度,则返回空串;pos大于字符串长度,抛出异常。


iconv:

iconv_open——申请一个字符集转换的描述符

#include <iconv.h>

iconv_t iconv_open(const char* tocode,const char* fromcode)

描述:

iconv_open()函数申请一个转换描述符,转换字符序列从编码fromcode到编码tocode

转换描述符包含转换状态,调用iconv_open创建以后,转换状态处于初始状态,调用iconv函数以后改变转换描述符的转换状态,(意味着转换描述符不能在多线程中同时使用)

返回值:

iconv_open函数返回一个新申请的转换描述符,出错时,返回(iconv_t)-1;



iconv函数:

size_t iconv(iconv_t cd,char **inbuf,size_t *inbytesleft,char **outbuf,size_t *outbytesleft);
此函数从inbuf中读取字符,转换后输出到outbuf中,inbytesleft用以记录还未转换的字符数,outbytesleft用以记录输出缓冲的剩余空间



setsockopt:

int setsockopt(
SOCKET s,
int level,
int optname,
const char* optval,
int optlen
);

s(套接字): 指向一个打开的套接口描述字
level:(级别): 指定选项代码的类型。
SOL_SOCKET: 基本套接口
IPPROTO_IP: IPv4套接口
IPPROTO_IPV6: IPv6套接口
IPPROTO_TCP: TCP套接口
optname(选项名): 选项名称
optval(选项值): 是一个指向变量的指针 类型:整形,套接口结构, 其他结构类型:linger{}, timeval{ }
optlen(选项长度) :optval 的大小

返回值:标志打开或关闭某个特征的二进制选项


Linux socket 进程通信:

(1)创建socket,类型为AF_LOCAL或AF_UNIX,表示用于进程通信:

[cpp]  view plain copy
  1. int server_fd;  
  2. int client_fd;//client file descriptor  
  3. struct sockaddr_un server_addr;   
  4. struct sockaddr_un client_addr;  
  5. size_t server_len,client_len;  
  6.   
  7. //cteate server socket  
  8. //delete old socket file  
  9. unlink(SERVER_NAME);  
  10. if ((server_fd = socket(AF_UNIX,  SOCK_STREAM,  0)) == -1) {  
  11.     perror("socket");  
  12.     exit(1);  
  13. }  

(2)命名socket。这里面有一个很关键的东西,socket进程通信命名方式有两种。一是普通的命名,socket会根据此命名创建一个同名的socket文件,客户端连接的时候通过读取该socket文件连接到socket服务端。这种方式的弊端是服务端必须对socket文件的路径具备写权限,客户端必须知道socket文件路径,且必须对该路径有读权限。另外一种命名方式是抽象命名空间,这种方式不需要创建socket文件,只需要命名一个全局名字,即可让客户端根据此名字进行连接。后者的实现过程与前者的差别是,后者在对地址结构成员sun_path数组赋值的时候,必须把第一个字节置0,即sun_path[0] = 0,下面用代码说明:

第一种方式:

server_addr.sun_family = AF_UNIX;  
strcpy(server_addr.sun_path,SERVER_NAME);  
server_len = sizeof(struct sockaddr_un);  
client_len = server_len;  
connect(server_fd , (const sockaddr*)&addr,server_len )


第二种方式:

[cpp]  view plain copy
  1. //name the socket  
  2. server_addr.sun_family = AF_UNIX;  
  3. strcpy(server_addr.sun_path, SERVER_NAME);  
  4. server_addr.sun_path[0]=0;  
  5. //server_len = sizeof(server_addr);  
  6. server_len = strlen(SERVER_NAME)  + offsetof(struct sockaddr_un, sun_path);  


其中,offsetof函数在#include <stddef.h>头文件中定义。因第二种方式的首字节置0,我们可以在命名字符串SERVER_NAME前添加一个占位字符串,例如:

[cpp]  view plain copy
  1. #define SERVER_NAME @socket_server  
前面的@符号就表示占位符,不算为实际名称。

UNIX Domain Socket与网络socket编程最明显的不同在于地址格式不同,用结构体sockaddr_un表示,网络编程的socket地址是IP地址加端口 号,而UNIX Domain Socket的地址是一个socket类型的文件在文件系统中的路径,



signal:

int sigprocmask(ubt how,const sigset_t*set,sigset_t *oldset)

how:用于指定信号修改的方式,可能选择有三种

SIG_BLOCK//将set所指向的信号集中包含的信号加到当前的信号掩码中。即信号掩码和set信号集进行或操作。

SIG_UNBLOCK//将set所指向的信号集中包含的信号从当前的信号掩码中删除。即信号掩码和set进行与操作。

SIG_SETMASK //将set的值设定为新的进程信号掩码。即set对信号掩码进行了赋值操作。

 

set:为指向信号集的指针,在此专指新设的信号集,如果仅想读取现在的屏蔽值,可将其置为NULL。

oldset:也是指向信号集的指针,在此存放原来的信号集。可用来检测信号掩码中存在什么信号。

返回说明:

成功执行时,返回0。失败返回-1,errno被设为EINVAL。



POSIX 线程 – pthread_sigmask:

 

在多线程的程序里,希望只在主线程中处理信号,可以使用

 

函数:

int pthread_sigmask (int how,

const sigset_t *set,

sigset_t *oset)


      用作在主调线程里控制信号掩码。

 

How:

SIG_BLOCK:     结果集是当前集合参数集的并集
SIG_UNBLOCK:  结果集是当前集合参数集的差集
SIG_SETMASK:  结果集是由参数集指向的集

 

头文件: <signal.h>

错误:   [EINVAL] how不是已定义值
提示:   除非信号在所有的线程里都阻塞,否则总能将异步信号传输给这个进程。

#include <pthread.h>
#include <stdio.h>
#include <sys/signal.h>
 
#define NUMTHREADS 3
void sighand(int signo);
 
void *threadfunc(void *parm)
{
    pthread_t             tid = pthread_self();
    int                   rc;
 
    printf("Thread %u entered/n", tid);
    rc = sleep(30);
    printf("Thread %u did not get expected results! rc=%d/n", tid, rc);
    return NULL;
}
 
void *threadmasked(void *parm)
{
    pthread_t             tid = pthread_self();
    sigset_t              mask;
    int                   rc;
 
    printf("Masked thread %lu entered/n", tid);
 
    sigfillset(&mask); /* Mask all allowed signals */
    rc = pthread_sigmask(SIG_BLOCK, &mask, NULL);
    if (rc != 0)
    {
        printf("%d, %s/n", rc, strerror(rc));
        return NULL;
    }
 
    rc = sleep(15);
    if (rc != 0)
    {
        printf("Masked thread %lu did not get expected results! "
                       "rc=%d /n", tid, rc);
        return NULL;
    }
    printf("Masked thread %lu completed masked work/n",
                tid);
    return NULL;
}
 
int main(int argc, char **argv)
{
    int                     rc;
    int                     i;
    struct sigaction        actions;
    pthread_t               threads[NUMTHREADS];
    pthread_t               maskedthreads[NUMTHREADS];
 
    printf("Enter Testcase - %s/n", argv[0]);
 
    printf("Set up the alarm handler for the process/n");
    memset(&actions, 0, sizeof(actions));
    sigemptyset(&actions.sa_mask);
    actions.sa_flags = 0;
    actions.sa_handler = sighand;
 
    rc = sigaction(SIGALRM,&actions,NULL);
 
    printf("Create masked and unmasked threads/n");
    for(i=0; i<NUMTHREADS; ++i)
    {
        rc = pthread_create(&threads[i], NULL, threadfunc, NULL);
        if (rc != 0)
        {
            printf("%d, %s/n", rc, strerror(rc));
            return -1;
        }
 
        rc = pthread_create(&maskedthreads[i], NULL, threadmasked, NULL);
        if (rc != 0)
        {
            printf("%d, %s/n", rc, strerror(rc));
            return -1;
        }
    }
 
    sleep(3);
    printf("Send a signal to masked and unmasked threads/n");
    for(i=0; i<NUMTHREADS; ++i)
    {
        rc = pthread_kill(threads[i], SIGALRM);
 
        rc = pthread_kill(maskedthreads[i], SIGALRM);
    }
 
    printf("Wait for masked and unmasked threads to complete/n");
    for(i=0; i<NUMTHREADS; ++i) {
        rc = pthread_join(threads[i], NULL);
 
        rc = pthread_join(maskedthreads[i], NULL);
    }
    printf("Main completed/n");
    return 0;
}
 
void sighand(int signo)
{
    pthread_t             tid = pthread_self();
 
    printf("Thread %lu in signal handler/n",
                             tid);
    return;
}



程序返回:

Enter Testcase - ./pthread_sigmask_test

Set up the alarm handler for the process

Create masked and unmasked threads

Thread 3086597040 entered

Masked thread 3076107184 entered

Thread 3065617328 entered

Masked thread 3055127472 entered

Thread 3044637616 entered

Masked thread 3034147760 entered

Send a signal to masked and unmasked threads

Wait for masked and unmasked threads to complete

Thread 3086597040 in signal handler

Thread 3086597040 did not get expected results! rc=27

Thread 3065617328 in signal handler

Thread 3065617328 did not get expected results! rc=27

Thread 3044637616 in signal handler

Thread 3044637616 did not get expected results! rc=27

Masked thread 3076107184 completed masked work

Masked thread 3055127472 completed masked work

Masked thread 3034147760 completed masked work

Main completed




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MyObject-C

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值