pthread_spin_lock无效?

sinat_30424685 2015-08-31 07:07:34
请大家看下下面的代码片段:
为什么thread1在pthread_spin_lock后,无法独占CPU呢?
这中间CPU还是会被thread2,thread3给抢占。是程序哪里写的不合理吗?谢谢!

部分运行结果:
----------------------
thread1 printf, count1=999
thread1 printf, count1=1000
pthread_spin_lock start
pthread_spin_lock is doing:0
thread2 printf, count2=1411
thread3 printf, count3=684
thread3 printf, count3=685
thread3 printf, count3=686
----------------------

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <pthread.h>

pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond;

pthread_spinlock_t vxworks_task_lock;

void* thread1(void *argv)
{
int count1 = 0;
int loop = 0;
int result = 0;

printf("thread1 start! \n ");

while(1)
{
printf("thread1 printf, count1=%d \n", count1);
count1 ++;
//sleep(1);

if(count1 > 1000)
{
break;
}
}

result = pthread_spin_lock( &vxworks_task_lock );
if(result !=0 )
{
printf(" pthread_spin_lock result is:%d\n", result);
}

printf(" pthread_spin_lock start\n");

for(loop =0; loop < 1000000000; loop++)
{
if(loop % 10000000 == 0)
{
printf(" pthread_spin_lock is doing:%d\n", loop);
}
}

pthread_spin_unlock( &vxworks_task_lock );

printf(" pthread_spin_lock end\n");

while(1)
{
printf("thread1 printf, count1=%d \n", count1);
count1 ++;

if(count1 > 1000000000)
{
break;
}

//sleep(1);
}

pthread_exit(NULL);
}

void* thread2(void *argv)
{
int count2 = 0;

printf("thread2 start! \n");

while(1)
{
printf("thread2 printf, count2=%d \n", count2);
count2 ++;

if(count2 > 1000000000)
{
break;
}
}

pthread_exit(NULL);

}

void* thread3(void *argv)
{
int count3 = 0;

printf("thread3 start! \n ");

while(1)
{
printf("thread3 printf, count3=%d \n", count3);
count3 ++;

if(count3 > 1000000000)
{
break;
}

sleep(1);
}

pthread_exit(NULL);

}


int main(int argc,char** argv)
{
pthread_t ptid1,ptid2,ptid3;
void * status;
int result = 0;

pthread_spin_init(&vxworks_task_lock, 0);

result = pthread_create(&ptid1,NULL,thread1,NULL);

if(result !=0 )
{
printf(" pthread_create1 result is:%d\n", result);
}

result = 0;

result = pthread_create(&ptid2,NULL,thread2,NULL);

if(result !=0 )
{
printf(" pthread_create2 result is:%d\n", result);
}

result = pthread_create(&ptid3,NULL,thread3,NULL);

if(result !=0 )
{
printf(" pthread_create3 result is:%d\n", result);
}

pthread_join(ptid1, &status);
pthread_join(ptid2, &status);
pthread_join(ptid3, &status);

return 0;
}
...全文
283 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
roarlion 2016-03-20
  • 打赏
  • 举报
回复
你应该在做VxWorks程序向GNU移植,pthread中找不到类似于vxworks下的taskLock() 禁止线程切换的函数,可以尝试一下在你重新封装的taskSpawn函数中将使用该函数创建的线程ID全部记录下来; 在某个线程调用taskLock时,首先获得调用taskLock的函数线程ID,再将不是该ID的线程全部挂起。 调用taskUnLock时,将所有保存的线程ID所对应的线程全部唤醒。
zhxianbin 2015-09-02
  • 打赏
  • 举报
回复
引用 6 楼 sinat_30424685 的回复:
[quote=引用 5 楼 zhxianbin 的回复:]
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/wait.h>

static pthread_mutex_t task_lock = PTHREAD_MUTEX_INITIALIZER;

static pthread_cond_t taskLock_change = PTHREAD_COND_INITIALIZER;

static pthread_mutex_t task_lock_handler = PTHREAD_MUTEX_INITIALIZER;

#define MYSIG_TASKLOCK 35

enum task_lock_status {
    TASK_UNLOCK = 0,
    TASK_LOCK = 1
};

enum	task_lock_status	g_lock_status;

typedef struct {
    pthread_t	pid;	/* ID of thread */
} PTHREAD_SIG;

#define PTHREAD_MAX 30
PTHREAD_SIG g_pthread_sig[PTHREAD_MAX];

void taskLock()
{
    pthread_t pid = 0;
    int loop;

    pthread_mutex_lock( &task_lock );
    /*g_lock_status = TASK_LOCK;

    pid = pthread_self();

    for(loop = 0; loop < PTHREAD_MAX; loop++)
    {
        if( (g_pthread_sig[loop].pid != 0) && (g_pthread_sig[loop].pid != pid) )
        {
            pthread_kill(g_pthread_sig[loop].pid, MYSIG_TASKLOCK);
        }
    }*/
}

void taskUnlock()
{
    g_lock_status = TASK_UNLOCK;

    //pthread_cond_broadcast( &taskLock_change );

    pthread_mutex_unlock( &task_lock );

    return;
}


void* thread_entry(void *argv)
{
    pthread_t pid = 0;
    int loop = 0;

    pid = pthread_self();
    printf("pthread_id:%ld start!\n", pid);

    while(1)
    {
        printf("pthread_id:%ld firstly printf, loop=%d\n", pid, loop);
        loop ++;

        if(loop > 10)
        {
            break;
        }
    }

    sleep(1);

    taskLock();

    printf("pthread_id:%ld lock start\n", pid);

    for(loop =0; loop < 20; loop++)
    {
        printf("pthread_id:%ld is doing:%d\n", pid, loop);
    }

    printf("pthread_id:%ld lock end\n", pid);

    taskUnlock();

    sleep(1);

    loop = 0;

    while(1)
    {
        printf("pthread_id:%ld secondly printf, loop=%d\n", pid, loop);
        loop ++;

        if(loop > 10)
        {
            break;
        }
    }

    sleep(1);

    printf("pthread_id:%ld end!\n", pid);

    pthread_exit(NULL);
}


void sig_handler_lock( int signal, siginfo_t *siginfo, void *u_contxt )
{
    pthread_cleanup_push( (void(*)(void *))pthread_mutex_unlock,
                          (void *)&task_lock_handler );

    while(g_lock_status == TASK_LOCK)
    {
        pthread_cond_wait( &taskLock_change, &task_lock_handler );
    }

    pthread_cleanup_pop( 1 );

    return;
}

int main(int argc,char** argv)
{
    pthread_t ptid;
    int loop = 0;

    int result = 0;
    void * status;

    pthread_cond_init(&taskLock_change, NULL);

    memset(g_pthread_sig, 0, sizeof(g_pthread_sig));

    struct sigaction sigact;

    memset(&sigact, 0, sizeof(sigact));
    sigact.sa_sigaction = sig_handler_lock;
    sigact.sa_flags = SA_SIGINFO;
    sigemptyset(&sigact.sa_mask);
    sigaction(MYSIG_TASKLOCK, &sigact, NULL);

    for(loop = 0; loop < PTHREAD_MAX; loop++)
    {
        result = pthread_create(&ptid, NULL, thread_entry, NULL);
        if(result !=0 )
        {
            printf("pthread_create result is:%d\n", result);
            return -1;
        }
        else
        {
            printf("pthread_create ptid=%ld\n", ptid);
            g_pthread_sig[loop].pid = ptid;
        }
    }

    for(loop = 0; loop < PTHREAD_MAX; loop++)
    {
        pthread_join(g_pthread_sig[loop].pid, &status);
    }

    return 0;
}
感谢回复,但是达不到想要的taskLock的效果。 这个是用互斥锁去做,但是假设某线程调用了taskLocj,但是其它thread没有去调用taskLock的话,其它线程还是可以跑下去的。 就达不到一个线程调用taskLock后,其它线程被阻塞的目的了。 请确认下。 [/quote] 不使用同步与互斥机制,自然无法同步和互斥,这不是互斥锁的问题,用其它机制也一样
sinat_30424685 2015-09-02
  • 打赏
  • 举报
回复
引用 5 楼 zhxianbin 的回复:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/wait.h>

static pthread_mutex_t task_lock = PTHREAD_MUTEX_INITIALIZER;

static pthread_cond_t taskLock_change = PTHREAD_COND_INITIALIZER;

static pthread_mutex_t task_lock_handler = PTHREAD_MUTEX_INITIALIZER;

#define MYSIG_TASKLOCK 35

enum task_lock_status {
    TASK_UNLOCK = 0,
    TASK_LOCK = 1
};

enum	task_lock_status	g_lock_status;

typedef struct {
    pthread_t	pid;	/* ID of thread */
} PTHREAD_SIG;

#define PTHREAD_MAX 30
PTHREAD_SIG g_pthread_sig[PTHREAD_MAX];

void taskLock()
{
    pthread_t pid = 0;
    int loop;

    pthread_mutex_lock( &task_lock );
    /*g_lock_status = TASK_LOCK;

    pid = pthread_self();

    for(loop = 0; loop < PTHREAD_MAX; loop++)
    {
        if( (g_pthread_sig[loop].pid != 0) && (g_pthread_sig[loop].pid != pid) )
        {
            pthread_kill(g_pthread_sig[loop].pid, MYSIG_TASKLOCK);
        }
    }*/
}

void taskUnlock()
{
    g_lock_status = TASK_UNLOCK;

    //pthread_cond_broadcast( &taskLock_change );

    pthread_mutex_unlock( &task_lock );

    return;
}


void* thread_entry(void *argv)
{
    pthread_t pid = 0;
    int loop = 0;

    pid = pthread_self();
    printf("pthread_id:%ld start!\n", pid);

    while(1)
    {
        printf("pthread_id:%ld firstly printf, loop=%d\n", pid, loop);
        loop ++;

        if(loop > 10)
        {
            break;
        }
    }

    sleep(1);

    taskLock();

    printf("pthread_id:%ld lock start\n", pid);

    for(loop =0; loop < 20; loop++)
    {
        printf("pthread_id:%ld is doing:%d\n", pid, loop);
    }

    printf("pthread_id:%ld lock end\n", pid);

    taskUnlock();

    sleep(1);

    loop = 0;

    while(1)
    {
        printf("pthread_id:%ld secondly printf, loop=%d\n", pid, loop);
        loop ++;

        if(loop > 10)
        {
            break;
        }
    }

    sleep(1);

    printf("pthread_id:%ld end!\n", pid);

    pthread_exit(NULL);
}


void sig_handler_lock( int signal, siginfo_t *siginfo, void *u_contxt )
{
    pthread_cleanup_push( (void(*)(void *))pthread_mutex_unlock,
                          (void *)&task_lock_handler );

    while(g_lock_status == TASK_LOCK)
    {
        pthread_cond_wait( &taskLock_change, &task_lock_handler );
    }

    pthread_cleanup_pop( 1 );

    return;
}

int main(int argc,char** argv)
{
    pthread_t ptid;
    int loop = 0;

    int result = 0;
    void * status;

    pthread_cond_init(&taskLock_change, NULL);

    memset(g_pthread_sig, 0, sizeof(g_pthread_sig));

    struct sigaction sigact;

    memset(&sigact, 0, sizeof(sigact));
    sigact.sa_sigaction = sig_handler_lock;
    sigact.sa_flags = SA_SIGINFO;
    sigemptyset(&sigact.sa_mask);
    sigaction(MYSIG_TASKLOCK, &sigact, NULL);

    for(loop = 0; loop < PTHREAD_MAX; loop++)
    {
        result = pthread_create(&ptid, NULL, thread_entry, NULL);
        if(result !=0 )
        {
            printf("pthread_create result is:%d\n", result);
            return -1;
        }
        else
        {
            printf("pthread_create ptid=%ld\n", ptid);
            g_pthread_sig[loop].pid = ptid;
        }
    }

    for(loop = 0; loop < PTHREAD_MAX; loop++)
    {
        pthread_join(g_pthread_sig[loop].pid, &status);
    }

    return 0;
}
感谢回复,但是达不到想要的taskLock的效果。 这个是用互斥锁去做,但是假设某线程调用了taskLocj,但是其它thread没有去调用taskLock的话,其它线程还是可以跑下去的。 就达不到一个线程调用taskLock后,其它线程被阻塞的目的了。 请确认下。
zhxianbin 2015-09-02
  • 打赏
  • 举报
回复
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/wait.h>

static pthread_mutex_t task_lock = PTHREAD_MUTEX_INITIALIZER;

static pthread_cond_t taskLock_change = PTHREAD_COND_INITIALIZER;

static pthread_mutex_t task_lock_handler = PTHREAD_MUTEX_INITIALIZER;

#define MYSIG_TASKLOCK 35

enum task_lock_status {
    TASK_UNLOCK = 0,
    TASK_LOCK = 1
};

enum	task_lock_status	g_lock_status;

typedef struct {
    pthread_t	pid;	/* ID of thread */
} PTHREAD_SIG;

#define PTHREAD_MAX 30
PTHREAD_SIG g_pthread_sig[PTHREAD_MAX];

void taskLock()
{
    pthread_t pid = 0;
    int loop;

    pthread_mutex_lock( &task_lock );
    /*g_lock_status = TASK_LOCK;

    pid = pthread_self();

    for(loop = 0; loop < PTHREAD_MAX; loop++)
    {
        if( (g_pthread_sig[loop].pid != 0) && (g_pthread_sig[loop].pid != pid) )
        {
            pthread_kill(g_pthread_sig[loop].pid, MYSIG_TASKLOCK);
        }
    }*/
}

void taskUnlock()
{
    g_lock_status = TASK_UNLOCK;

    //pthread_cond_broadcast( &taskLock_change );

    pthread_mutex_unlock( &task_lock );

    return;
}


void* thread_entry(void *argv)
{
    pthread_t pid = 0;
    int loop = 0;

    pid = pthread_self();
    printf("pthread_id:%ld start!\n", pid);

    while(1)
    {
        printf("pthread_id:%ld firstly printf, loop=%d\n", pid, loop);
        loop ++;

        if(loop > 10)
        {
            break;
        }
    }

    sleep(1);

    taskLock();

    printf("pthread_id:%ld lock start\n", pid);

    for(loop =0; loop < 20; loop++)
    {
        printf("pthread_id:%ld is doing:%d\n", pid, loop);
    }

    printf("pthread_id:%ld lock end\n", pid);

    taskUnlock();

    sleep(1);

    loop = 0;

    while(1)
    {
        printf("pthread_id:%ld secondly printf, loop=%d\n", pid, loop);
        loop ++;

        if(loop > 10)
        {
            break;
        }
    }

    sleep(1);

    printf("pthread_id:%ld end!\n", pid);

    pthread_exit(NULL);
}


void sig_handler_lock( int signal, siginfo_t *siginfo, void *u_contxt )
{
    pthread_cleanup_push( (void(*)(void *))pthread_mutex_unlock,
                          (void *)&task_lock_handler );

    while(g_lock_status == TASK_LOCK)
    {
        pthread_cond_wait( &taskLock_change, &task_lock_handler );
    }

    pthread_cleanup_pop( 1 );

    return;
}

int main(int argc,char** argv)
{
    pthread_t ptid;
    int loop = 0;

    int result = 0;
    void * status;

    pthread_cond_init(&taskLock_change, NULL);

    memset(g_pthread_sig, 0, sizeof(g_pthread_sig));

    struct sigaction sigact;

    memset(&sigact, 0, sizeof(sigact));
    sigact.sa_sigaction = sig_handler_lock;
    sigact.sa_flags = SA_SIGINFO;
    sigemptyset(&sigact.sa_mask);
    sigaction(MYSIG_TASKLOCK, &sigact, NULL);

    for(loop = 0; loop < PTHREAD_MAX; loop++)
    {
        result = pthread_create(&ptid, NULL, thread_entry, NULL);
        if(result !=0 )
        {
            printf("pthread_create result is:%d\n", result);
            return -1;
        }
        else
        {
            printf("pthread_create ptid=%ld\n", ptid);
            g_pthread_sig[loop].pid = ptid;
        }
    }

    for(loop = 0; loop < PTHREAD_MAX; loop++)
    {
        pthread_join(g_pthread_sig[loop].pid, &status);
    }

    return 0;
}
zhxianbin 2015-09-01
  • 打赏
  • 举报
回复
其它线程无法获得锁就阻塞了
sinat_30424685 2015-09-01
  • 打赏
  • 举报
回复
引用 1 楼 zhxianbin 的回复:
为什么不用 pthread_mutex_lock,pthread_spin_lock 没用过
pthread_mutex_lock应该是两个线程间互斥吧。 pthread_spin_lock 为的是实现CPU的独占,即其它线程无法占据CPU。 这样理解对吧? 功能上还是有所差异的。
sinat_30424685 2015-09-01
  • 打赏
  • 举报
回复
引用 3 楼 zhxianbin 的回复:
其它线程无法获得锁就阻塞了
帮忙看下下面的代码为什么会产生死锁? 有无解决方案,谢谢! 目的如下,其中某个线程调用了taskLock之后,就会给其它线程发一个SIG,其它线程收到SIG之后,就要把自己阻塞起来。 于是在taskLock的代码中,先lock住一个mutex lock,然后发信号给其它线程。 其他线程收到SIG后,一直等待一个条件变量taskLock_change。 在taskUnlock中,广播一个条件变量taskLock_change出去,其它线程收到这个条件变量后,就停止阻塞。 #include <stdlib.h> #include <stdio.h> #include <string.h> #include <pthread.h> #include <sys/types.h> #include <sys/wait.h> static pthread_mutex_t task_lock = PTHREAD_MUTEX_INITIALIZER; static pthread_cond_t taskLock_change = PTHREAD_COND_INITIALIZER; static pthread_mutex_t task_lock_handler = PTHREAD_MUTEX_INITIALIZER; #define MYSIG_TASKLOCK 35 enum task_lock_status{ TASK_UNLOCK = 0, TASK_LOCK = 1 }; enum task_lock_status g_lock_status; typedef struct{ pthread_t pid; /* ID of thread */ } PTHREAD_SIG; #define PTHREAD_MAX 30 PTHREAD_SIG g_pthread_sig[PTHREAD_MAX]; void taskLock() { pthread_t pid = 0; int loop; pthread_mutex_lock( &task_lock ); g_lock_status = TASK_LOCK; pid = pthread_self(); for(loop = 0; loop < PTHREAD_MAX; loop++) { if( (g_pthread_sig[loop].pid != 0) && (g_pthread_sig[loop].pid != pid) ) { pthread_kill(g_pthread_sig[loop].pid, MYSIG_TASKLOCK); } } } void taskUnlock() { g_lock_status = TASK_UNLOCK; pthread_cond_broadcast( &taskLock_change ); pthread_mutex_unlock( &task_lock ); return; } void* thread_entry(void *argv) { pthread_t pid = 0; int loop = 0; pid = pthread_self(); printf("pthread_id:%ld start!\n", pid); while(1) { printf("pthread_id:%ld firstly printf, loop=%d\n", pid, loop); loop ++; if(loop > 1000) { break; } } sleep(1); taskLock(); printf("pthread_id:%ld lock start\n", pid); for(loop =0; loop < 10000; loop++) { printf("pthread_id:%ld is doing:%d\n", pid, loop); } printf("pthread_id:%ld lock end\n", pid); taskUnlock(); sleep(1); loop = 0; while(1) { printf("pthread_id:%ld secondly printf, loop=%d\n", pid, loop); loop ++; if(loop > 1000) { break; } } sleep(1); printf("pthread_id:%ld end!\n", pid); pthread_exit(NULL); } void sig_handler_lock( int signal, siginfo_t *siginfo, void *u_contxt ) { pthread_cleanup_push( (void(*)(void *))pthread_mutex_unlock, (void *)&task_lock_handler ); while(g_lock_status == TASK_LOCK) { pthread_cond_wait( &taskLock_change, &task_lock_handler ); } pthread_cleanup_pop( 1 ); return; } int main(int argc,char** argv) { pthread_t ptid; int loop = 0; int result = 0; void * status; pthread_cond_init(&taskLock_change, NULL); memset(g_pthread_sig, 0, sizeof(g_pthread_sig)); struct sigaction sigact; memset(&sigact, 0, sizeof(sigact)); sigact.sa_sigaction = sig_handler_lock; sigact.sa_flags = SA_SIGINFO; sigemptyset(&sigact.sa_mask); sigaction(MYSIG_TASKLOCK, &sigact, NULL); for(loop = 0; loop < PTHREAD_MAX; loop++) { result = pthread_create(&ptid, NULL, thread_entry, NULL); if(result !=0 ) { printf("pthread_create result is:%d\n", result); return -1; } else { printf("pthread_create ptid=%ld\n", ptid); g_pthread_sig[loop].pid = ptid; } } for(loop = 0; loop < PTHREAD_MAX; loop++) { pthread_join(g_pthread_sig[loop].pid, &status); } return 0; }
zhxianbin 2015-09-01
  • 打赏
  • 举报
回复
为什么不用 pthread_mutex_lock,pthread_spin_lock 没用过

23,116

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧